home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 37 / Amiga Format CD37 (1999-02-16)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-03].iso / -screenplay- / shareware / 3d_core / we.e < prev    next >
Text File  |  1999-01-04  |  111KB  |  2,788 lines

  1. /*****************************************************/
  2. /**** 3D_Core World Editor Version 1.20  24/14/97 ****/
  3. /****  Copyright (c) Jonathan Gregory 1995-1997   ****/
  4. /*****************************************************/
  5.  
  6. /* NOTE - Version info set in initialise() */
  7.  
  8. OPT PREPROCESS                      /* Allow use of macros */
  9. OPT LARGE
  10.  
  11. /****************/
  12. /*** Includes ***/
  13. /****************/
  14.  
  15. MODULE   'tools/EasyGUI_Orig',      /* Setup Modules to include */
  16.          'tools/constructors',
  17.          'graphics/view',
  18.          'graphics/text',
  19.          'graphics/rastport',
  20.          'intuition/intuition',
  21.          'intuition/screens',
  22.          'intuition/gadgetclass',
  23.          'utility/tagitem',
  24.          'diskfont',
  25.          'dos',
  26.          'dos/dos',
  27.          'exec/ports',
  28.          'exec/lists',
  29.          'exec/nodes',
  30.          'exec/memory',
  31.          'gadtools',
  32.          'libraries/gadtools',
  33.          'asl',
  34.          'libraries/asl'
  35.  
  36. /*****************/
  37. /*** Constants ***/
  38. /*****************/
  39.  
  40. CONST DEFSCRMODE  =  V_HIRES OR V_LACE
  41. CONST MAPWINIDCMP =  IDCMP_GADGETDOWN OR IDCMP_GADGETUP OR IDCMP_INTUITICKS OR IDCMP_MOUSEBUTTONS OR IDCMP_MENUPICK
  42. CONST DRAGIDCMP   =  IDCMP_INTUITICKS OR IDCMP_MOUSEBUTTONS
  43. CONST MAPWINSIZE  =  400
  44. CONST VSCRLID     =  2000
  45. CONST HSCRLID     =  2001
  46. CONST NULGADID    =  2999
  47. CONST OBDFCOUNT   =  10                              /* Max No. of ObjDef's in LineDef */
  48.  
  49.  
  50. CONST MAXCOORD    =  32768                           /* Must not be > than 16 bit !!   */
  51. CONST MAXZOOM     =  100
  52. CONST MINZOOM     =  1
  53. CONST MAXALT      =  20000
  54. CONST MINALT      = -20000
  55. CONST MAXHEAD     =  1023
  56. CONST MINHEAD     =  0
  57. CONST MAXSIZE     =  32767
  58. CONST MINSIZE     =  1
  59. CONST MAXCRAD     =  32767
  60. CONST MINCRAD     =  0
  61. CONST MINOBID     =  $FFFFFFFF
  62. CONST MAXOBID     =  $7FFFFFFF
  63.  
  64. CONST MINWID      =  1
  65. CONST MAXWID      =  10000
  66. CONST MINDEP      =  1
  67. CONST MAXDEP      =  10000
  68. CONST MINFLR      = -10000
  69. CONST MAXFLR      =  10000
  70. CONST MINCEIL     = -10000
  71. CONST MAXCEIL     =  10000
  72.  
  73. CONST OBJDEFMAGIC = $4F424446                      /* Magic Disk File ID's             */
  74. CONST WOBJMAGIC   = $574F424A
  75. CONST LINDEFMAGIC = $4C4E4446
  76.  
  77. ENUM GREY,BLACK,WHITE,BLUE,RED,GREEN,BLUE,ORANGE   /* Enumerate Colours                */ 
  78.  
  79. ENUM WE_MODE_ADD,WE_MODE_DEL,WE_MODE_EDIT          /* Enumerate WorldEd Modes          */
  80.  
  81. ENUM WE_TYPE_OBJ,WE_TYPE_COL                       /* Enumerate WorldEd Edit Types     */
  82.  
  83. ENUM  MNUNEW=100, MNUOPEN, MNUSAVE, MNUABOUT, MNULNOPEN, MNULNSTAT
  84. CONST MNUSTART= 100
  85. CONST MNUEND  = 150
  86.  
  87. CONST ASLWIDTH=320, ASLHEIGHT=400, ASLLEFTEDGE=20, ASLTOPEDGE=20, PATHLEN=120
  88.  
  89. /*********************/
  90. /*** Define Macros ***/
  91. /*********************/
  92.  
  93. #define UNSIGNED(x) (x AND $FFFF)
  94.  
  95. /*****************************/
  96. /*** Structure Definitions ***/
  97. /*****************************/
  98.  
  99. /* Note the following structure is a generic disk file header */
  100.  
  101. OBJECT header                       /*** WObject Disk File Header ***/
  102.   magic,                            /*     File Magic ID Number     */
  103.   wobcount,                         /*      File WObject Count      */
  104.   colcount                          /*      File ColArea Count      */
  105. ENDOBJECT
  106.  
  107. OBJECT obdfheader                   /*** ObjDef File Header Info ***/
  108.   magic,                            /*     File Magic ID Number    */
  109.   count                             /*  Number of ObjDefs in File  */
  110. ENDOBJECT
  111.  
  112. OBJECT objdef                       /***   Base Object Definition    ***/
  113.   id,                               /*   Object Definition ID Number   */
  114.   name[16]:ARRAY OF CHAR,           /*   Object Definition Name 15+1   */
  115.   size:INT,                         /*    Basic Object Size (Scale)    */
  116.   frames:INT,                       /*      Number of anim frames      */
  117.   views:INT,                        /*     Number of Views 1/8/16      */
  118.   fdelay:INT,                       /*  Anim Frame Delay in V-Blanks   */
  119.   flags,                            /*     Object definition Flags     */
  120.   imgid[32]:ARRAY OF LONG           /*     Chunky Image ID's Array     */
  121. ENDOBJECT
  122.  
  123. OBJECT wobject                      /***   World Object Definition   ***/
  124.   x,y,                              /*   Object World X and Y Coords   */
  125.   height,                           /* Objects Height Within the World */
  126.   heading,                          /*  Heading 0-359 Degrees (UWORD)  */
  127.   size,                             /* Object Size For Scaling (UWORD) */
  128.   radius,                           /* Objects Collsion Radius (UWORD) */
  129.   speed,                            /* Current Speed of Object (UWORD) */
  130.   obid,                             /* Object Type/ID (LONG)           */
  131.   objdef[4]:ARRAY OF LONG           /* Array of Object Definition ID's */
  132. ENDOBJECT
  133.  
  134. OBJECT status                       /***     Interface Status Structure     ***/
  135.   mode,                             /*          Current editing mode          */
  136.   edtype,                           /*       Current Type Being Edited        */
  137.   zoom,                             /*       Current zoom setting 1-100       */
  138.   x,y,                              /*  Current Map Top Left Co-ord Settings  */
  139.   wx,wy,                            /*  Current Object World Co-ord Settings  */
  140.   wid,dep,flr,ceil,                 /*    Current Collision Zone Settings     */
  141.   alt,head,size,crad,               /* Current Alt,Head,Size,Radius Settings  */
  142.   obid,pass                         /* Current Object ID & Passable Settings  */
  143.   actscroll:PTR TO gadget,          /* Pointer to active (down) scroll gadget */
  144.   mcyc,                             /* Edit mode cycle gadget E-list pointer  */
  145.   tcyc,                             /* Edit type cycle gadget E-list pointer  */
  146.   zint,                             /*   Zoom integer gadget E-list pointer   */
  147.   zsld,                             /*   Zoom slide gadget E-List pointer     */
  148.   mxint,myint,                      /* Map X,Y Co-ord gadget E-List Pointers  */
  149.   wxint,wyint,                      /* Obj X,Y Co-ord gadget E-List Pointers  */
  150.   widint,depint,flrint,ceilint,     /*  Collison zone gadget E-List Pointers  */
  151.   altint,headint,sizeint,           /* Misc Object Related Gadget E-List Ptrs */
  152.   cradint,obidint,passchk           /* Misc Object Related Gadget E-List Ptrs */
  153.   obdfstr[4]:ARRAY OF LONG,         /*    Pointer to ObjDef Gadget E-Lists    */
  154.   obdfbut[4]:ARRAY OF LONG,         /*  Ptr to ObjDef Button Gadget E-Lists   */
  155.   obdfid[4]:ARRAY OF LONG,          /*       Current Select ObjDef ID's       */
  156.   defcount,defptr:PTR TO objdef,    /* Number of ObjDefs & Array base pointer */
  157.   deflist:PTR TO lh,                /* Pointer to Def's List Header (execlst) */
  158.   woblist:PTR TO lh,                /* Pointer to wobject List Header (exec)  */
  159.   linelist:PTR TO lh,               /* Pointer to linedef List Header (exec)  */
  160.   collist:PTR TO lh,                /* Pointer to colarea List Header (exec)  */
  161.   actwobj:PTR TO wobject,           /*        Pointer to active wobject       */
  162.   actcol:PTR TO colarea,            /*        Pointer to active colarea       */
  163.   mouse,                            /*   Current mouse select button status   */
  164.   mousesx,mousesy,                  /* Start Co-ords of Down-Drag-Release Op  */
  165.   mouseex,mouseey,                  /*  End Co-ords of Down-Drag-Release Op   */
  166.   mousecount                        /*   Mouse drag draw op's counter/flag    */
  167. ENDOBJECT
  168.  
  169. OBJECT defitem                      /*** Exec List Version of ObjDef Array  ***/
  170.   node:ln,                          /*             Exec list node             */
  171.   id,                               /*          Object Definition ID          */
  172.   name[16]:ARRAY OF CHAR            /*     Object Definition Name String      */
  173. ENDOBJECT
  174.  
  175. OBJECT wobitem                      /*** Exec List Version of WObject data  ***/
  176.   node:ln,                          /*             Exec list node             */
  177.   wob:wobject,                      /*         World Object Structure         */
  178.   select                            /*     Internal group selection data      */
  179. ENDOBJECT
  180.  
  181. /*
  182. OBJECT linedef                      /***   Basic Line Drawing  Definition   ***/
  183.   name[16]:ARRAY OF CHAR,           /*        Name of line Definition         */
  184.   spacing,                          /*   Spacing between succesive objects    */
  185.   height,                           /*    Object Height Within the World      */
  186.   heading,                          /*         Heading 0-359 Degrees          */
  187.   size,                             /*        Object Size For Scaling         */
  188.   radius,                           /*        Object Collision Radius         */
  189.   id,                               /*   Type/ID of LineDef derived Objects   */
  190.   objdef[16]:ARRAY OF LONG          /*    Array of Object Definition ID's     */
  191. ENDOBJECT
  192.  
  193. OBJECT lineitem                     /***   Exec List Version of Line Def.   ***/
  194.   node:ln,                          /*             Exec list node             */ 
  195.   ldf:linedef                       /*       Line Definition Structure        */
  196. ENDOBJECT
  197. */
  198.  
  199. OBJECT colarea                      /***   Basic Collision Area Structure   ***/
  200.   x,y,                              /*        Co-ords of Collision Box        */
  201.   width,depth,                      /*      Width/Depth of Collision Box      */
  202.   floor,ceil,                       /*     Floor/Ceiling of Collision Box     */
  203.   id                                /*  ID Number Allocated to Collision Box  */
  204. ENDOBJECT
  205.  
  206. OBJECT colitem                      /*** Exec List Version of Collision Box ***/
  207.   node:ln                           /*             Exec List Node             */
  208.   col:colarea,                      /*        Actual colarea Structure        */
  209.   select                            /*        Extended Selection Info         */
  210. ENDOBJECT
  211.  
  212. OBJECT guiwork                      /***  Structure for GUI info transfer   ***/
  213.   str:PTR TO CHAR,
  214.   val
  215. ENDOBJECT
  216.  
  217. OBJECT screenmode                   /***  Screen mode from selectscreen()   ***/
  218.   mode,                             /*             Screen mode ID             */
  219.   width,                            /*         Screen width selected          */
  220.   height,                           /*         Screen height selected         */
  221.   depth,                            /*         Screen depth selected          */
  222.   minwidth,                         /*         Minimum width allowable        */
  223.   minheight,                        /*         Minimum height allowable       */
  224.   mindepth,                         /*         Minimum depth allowable        */
  225.   gads                              /* True if Width,Height & Depth gads req. */
  226. ENDOBJECT
  227.  
  228. OBJECT linedef                     /*** Line Def File Structure ***/
  229.   magic,                            /*     File Magic ID Number    */
  230.   space,                            /*      Object Seperation      */
  231.   obdfid[OBDFCOUNT]:ARRAY OF LONG   /*     Array of ObjDef ID's    */
  232. ENDOBJECT
  233.  
  234. /*******************/
  235. /*** Global Data ***/
  236. /*******************/
  237.  
  238. DEF stitle,abouttitle
  239.  
  240. DEF diskfontbase=NIL                 /* diskfont.library base pointer  */
  241.  
  242. DEF scrn=NIL:PTR TO screen           /* Screen pointer                 */
  243. DEF visinfo=NIL                      /* Pointer to Visual Info         */
  244. DEF fontattr=NIL:PTR TO textattr     /* Pointer to fontattr            */
  245. DEF font=NIL                         /* Pointer to font                */
  246. DEF filereq=NIL:PTR TO filerequester /* Pointer to FileRequester       */
  247. DEF linereq=NIL:PTR TO filerequester /* Pointer to Line FileRequester  */
  248. DEF linedef=NIL:PTR TO linedef       /* Currently Loaded LineDef Ptr   */
  249.  
  250. DEF bdwin=NIL:PTR TO window          /* Pointer to backdrop window     */
  251. DEF mapwin=NIL:PTR TO window         /* Pointer to map window          */
  252. DEF mapsig=NIL                       /* Map Window Port Signal Mask    */
  253. DEF congh=NIL:PTR TO guihandle       /* GUI Handle for control window  */
  254. DEF menustrip=NIL                    /* Pointer to menustrip           */
  255.  
  256. DEF vscrl=NIL:PTR TO gadget          /* Pointer Vertical Scroller      */
  257. DEF vimg =NIL:PTR TO image           /* Vert scroller image            */
  258. DEF vinfo=NIL:PTR TO propinfo        /* Vert scroller propinfo         */
  259.                                      
  260. DEF hscrl=NIL:PTR TO gadget          /* Pointer to Horizontal Scroller */
  261. DEF himg =NIL:PTR TO image           /* Horiz scroller image           */
  262. DEF hinfo=NIL:PTR TO propinfo        /* Horiz scroller propinfo        */
  263.  
  264. DEF nulinfo=NIL:PTR TO boolinfo      /* Null gadget stuff !!!!!!       */
  265. DEF nulgad =NIL:PTR TO gadget
  266.  
  267. DEF stat=NIL:PTR TO status           /* Pointer to interface status    */
  268.  
  269. DEF s0[15]:STRING,s1[15]:STRING      /* Current contents of string gadgets */
  270. DEF s2[15]:STRING,s3[15]:STRING      /* Updated Automativally by Gadgets   */
  271.  
  272. DEF os0[15]:STRING,os1[15]:STRING    /* What should be in string gadgets   */
  273. DEF os2[15]:STRING,os3[15]:STRING    /* used to reset after manual change  */
  274.  
  275. DEF tantab[89]:ARRAY OF LONG         /* Tangents Table Space */
  276.  
  277. /*******************/
  278. /**** Main line ****/
  279. /*******************/
  280.  
  281. PROC main() HANDLE
  282.    DEF ret
  283.  
  284.    ret:=initialise()
  285.    IF ret=0 THEN waitevent()
  286.  
  287. EXCEPT DO
  288.    cleanup()
  289.    ReThrow()
  290. ENDPROC
  291.  
  292. /********************/
  293. /**** Initialise ****/
  294. /********************/
  295.  
  296. /* Returns 0 on success, otherwise 1 */
  297.  
  298. PROC initialise()
  299.   DEF ret
  300.  
  301.   stitle:='World Editor v1.12'                           /*** Set Version Strings  ***/
  302.  
  303.   abouttitle:='        3DCore - World Editor   \n'+
  304.               '          v1.12  24/04/1997     \n'+
  305.               'Copyright (c) Jonathan Gregory 1995-97'
  306.  
  307.   diskfontbase:=OpenLibrary('diskfont.library',37)       /* Open any required Libs   */
  308.   IF diskfontbase=NIL                                    /* Report if failed to open */
  309.     WriteF('Requires diskfont.library v37 or higher\n')
  310.     RETURN 1
  311.   ENDIF
  312.  
  313.   gadtoolsbase:=OpenLibrary('gadtools.library',0)        /* Open Gadtools Library    */
  314.   IF gadtoolsbase=NIL                                    /* Report if failed to open */
  315.     WriteF('Failed to open GadTools library\n')
  316.     RETURN 1
  317.   ENDIF
  318.  
  319.   aslbase:=OpenLibrary('asl.library',37)
  320.   IF aslbase=NIL
  321.     WriteF('Requires Asl.Library v37 or higher\n')
  322.     RETURN 1
  323.   ENDIF
  324.  
  325.   ret:=buildscreen()                                     /* Build Screen & Setup Windows    */
  326.   IF ret=0 THEN ret:=loadobjdefs(1)                      /* Load ObjDefs & Conv to ExecList */
  327.   IF ret=0 THEN ret:=initmisc()                          /* Init Misc resources             */
  328.   IF ret=0
  329.     stat.woblist :=newlist()                             /* Allocate new list headers       */
  330.     stat.linelist:=newlist()
  331.     stat.collist :=newlist()
  332.     stat.actwobj :=NIL
  333.     stat.actcol  :=NIL
  334.   ENDIF
  335. ENDPROC ret
  336.  
  337. /***************************************/
  338. /**** Display Screen Mode Requester ****/
  339. /***************************************/
  340.  
  341. PROC selectscreen(sm:PTR TO screenmode)
  342.   DEF smr:PTR TO screenmoderequester
  343.   DEF res=0
  344.  
  345.   smr:=AllocAslRequest(ASL_SCREENMODEREQUEST,
  346.                       [ASL_HAIL,                   'The Screen Mode requester',
  347.                        ASL_HEIGHT,                 ASLHEIGHT,
  348.                        ASL_WIDTH,                  ASLWIDTH,
  349.                        ASL_LEFTEDGE,               ASLLEFTEDGE,
  350.                        ASL_TOPEDGE,                ASLTOPEDGE,
  351.                        ASL_OKTEXT,                 'Okay',
  352.                        ASL_CANCELTEXT,             'Cancel',
  353.                        ASLSM_INITIALDISPLAYID,     sm.mode,
  354.                        ASLSM_INITIALDISPLAYWIDTH,  sm.width,
  355.                        ASLSM_INITIALDISPLAYHEIGHT, sm.height,
  356.                        ASLSM_INITIALDISPLAYDEPTH,  sm.depth,
  357.                        ASLSM_MINWIDTH,             sm.minwidth,
  358.                        ASLSM_MINHEIGHT,            sm.minheight,
  359.                        ASLSM_MINDEPTH,             sm.mindepth,
  360.                        ASLSM_DOWIDTH,              sm.gads,
  361.                        ASLSM_DOHEIGHT,             sm.gads,
  362.                        ASLSM_DODEPTH,              sm.gads,
  363.                        NIL])
  364.  
  365.   IF smr 
  366.     res:=AslRequest(smr, NIL)
  367.     IF res
  368.        sm.mode  :=smr.displayid
  369.        sm.width :=smr.displaywidth
  370.        sm.height:=smr.displayheight
  371.        sm.depth :=smr.displaydepth
  372.     ENDIF
  373.     FreeAslRequest(smr)
  374.   ENDIF
  375.  
  376. ENDPROC res
  377.  
  378. /**********************************/
  379. /**** Load & Save screen prefs ****/
  380. /**********************************/
  381.  
  382. PROC loadscreenprefs(sm)
  383.   DEF handle
  384.  
  385.   handle:=Open('ENVARC:WorldED_Screen.prefs',OLDFILE)
  386.   IF handle
  387.     Read(handle,sm,SIZEOF screenmode)
  388.     Close(handle)
  389.   ENDIF
  390. ENDPROC
  391.  
  392. PROC savescreenprefs(sm)
  393.   DEF handle
  394.  
  395.   handle:=Open('ENVARC:WorldED_Screen.prefs',NEWFILE)
  396.   IF handle
  397.     Write(handle,sm,SIZEOF screenmode)
  398.     Close(handle)
  399.   ENDIF
  400. ENDPROC
  401.  
  402. /******************************/
  403. /**** Build Screen Display ****/
  404. /******************************/
  405.  
  406. /* Returns 0 on success, otherwise 1 */
  407.  
  408. PROC buildscreen()
  409.   DEF mwtitle,top,tags[40]:ARRAY OF LONG
  410.   DEF mcyc,tcyc,zint,zsld,mxint,myint,wxint,wyint,menus
  411.   DEF widint,depint,flrint,ceilint
  412.   DEF obdf0,obdf1,obdf2,obdf3,obdfb0,obdfb1,obdfb2,obdfb3
  413.   DEF alt,head,size,crad,obid,pass
  414.   DEF sm:PTR TO screenmode,win:PTR TO window,res
  415.  
  416.   stat:=NEW [0,1,0,0,0,0,0,0,512]:status            /* Intialise program status structure */
  417.  
  418.   fontattr:=['Courier.font',13,0,0]:textattr                        /* Setup font attribs */
  419.   font:=OpenDiskFont(fontattr)                                      /* Open disk font     */
  420.   IF font=0                                                         /* If failed report   */
  421.      WriteF('Could not open \s !!\n',fontattr.name)
  422.      RETURN 1
  423.   ENDIF
  424.  
  425.   sm:=NEW [DEFSCRMODE,640,480,3,640,480,3,TRUE]:screenmode          /* Allocate screenmode */
  426.   loadscreenprefs(sm)
  427.   res:=selectscreen(sm)                                             /* Put up requester    */
  428.   IF res=NIL THEN RETURN 1                                          /* If cancel exit      */
  429.   savescreenprefs(sm)
  430.  
  431.   tags:=[SA_WIDTH,sm.width,    SA_HEIGHT,sm.height,                 /* Setup Screen Tags   */
  432.          SA_DEPTH,sm.depth,    SA_PENS,[-1],
  433.          SA_DISPLAYID,sm.mode, SA_TITLE,stitle,
  434.          SA_FONT, fontattr,
  435.          TAG_END,NIL]
  436.  
  437.   scrn:=OpenScreenTagList(NIL,tags)                                 /* Open Screen         */
  438.   IF scrn=0                                                         /* If failed - report  */
  439.      WriteF('Could not open screen !!\n')
  440.      RETURN 1
  441.   ENDIF
  442.  
  443.   SetColour(scrn,RED   ,255,0,0)                                    /* Set Pen 4 to Red    */
  444.   SetColour(scrn,GREEN ,0,255,0)                                    /* Set Pen 5 to Green  */
  445.   SetColour(scrn,BLUE  ,0,0,255)                                    /* Set Pen 6 to Blue   */
  446.   SetColour(scrn,ORANGE,255,128,0)                                  /* Set Pen 7 to Orange */
  447.  
  448.   top:=scrn.barheight+1
  449.   tags:=[WA_LEFT,0, WA_TOP,(scrn.barheight)+2,              /* Setup Backdrop Window Tags  */
  450.         WA_CUSTOMSCREEN,scrn, WA_SMARTREFRESH,TRUE,
  451.         WA_WIDTH,sm.width, WA_HEIGHT,sm.height-top,
  452.         WA_BACKDROP,TRUE, WA_BORDERLESS,TRUE,
  453.         TAG_END,NIL]
  454.   bdwin:=OpenWindowTagList(NIL,tags)
  455.  
  456.   IF bdwin=NIL                                                       /* If failed - report */
  457.      WriteF('Could not open backdrop window !!\n')
  458.      RETURN 1
  459.   ENDIF
  460.   drawbackdropwin()                                                       /* Draw backdrop */
  461.  
  462.   FastDisposeList(sm)                                               /* Dispose screenmode  */
  463.  
  464.   top:=scrn.wbortop+scrn.font.ysize+2                                 /* Calc top position */
  465.   NEW vimg,himg                                                       /* Initialise Images */
  466.  
  467.   vinfo:=NEW [PROPNEWLOOK OR AUTOKNOB OR FREEVERT,                    /* Build Scrollers   */
  468.               0,0,-1,MAXBODY]:propinfo
  469.  
  470.   hinfo:=NEW [PROPNEWLOOK OR AUTOKNOB OR FREEHORIZ,
  471.               0,0,MAXBODY,-1]:propinfo
  472.  
  473.   vscrl:=NEW [NIL,-10,top,8,-top-13,                           /* Next,x,y,w,h             */
  474.     GFLG_RELRIGHT OR GFLG_RELHEIGHT,                           /* Gadget flags             */
  475.     GACT_RELVERIFY OR GACT_IMMEDIATE OR GACT_RIGHTBORDER,      /* Activation flags         */
  476.     GTYP_PROPGADGET OR GTYP_GZZGADGET,                         /* Gadget type (prop)       */
  477.     vimg,NIL,NIL,NIL,                                          /* Render x 2, text & RFU   */
  478.     vinfo,VSCRLID]:gadget                                      /* Propinfo, ID & User Data */
  479.  
  480.   hscrl:=NEW [vscrl,3,-10,-16,8,                               /* Next,x,y,w,h             */
  481.     GFLG_RELBOTTOM OR GFLG_RELWIDTH,                           /* Gadget flags             */
  482.     GACT_RELVERIFY OR GACT_IMMEDIATE OR GACT_BOTTOMBORDER,     /* Activation flags         */
  483.     GTYP_PROPGADGET OR GTYP_GZZGADGET,                         /* Gadget type (prop)       */
  484.     himg,NIL,NIL,NIL,                                          /* Render x 2, text & RFU   */
  485.     hinfo,HSCRLID]:gadget                                      /* Propinfo, ID & User Data */
  486.  
  487.   nulinfo:=NEW [BOOLMASK]                                      /* Setup null border gadget */
  488.   nulgad:=NEW[hscrl,-13,-13,4,4,                               /* Used to size borders !!! */
  489.     GFLG_RELBOTTOM OR GFLG_RELRIGHT,
  490.     GACT_BOTTOMBORDER OR GACT_RIGHTBORDER,
  491.     GTYP_BOOLGADGET OR GTYP_GZZGADGET,
  492.     NIL,NIL,NIL,NIL,nulinfo,NULGADID]:gadget
  493.  
  494.  mwtitle:='Map View'                                                 /* Setup Title String */
  495.  tags:=[WA_LEFT,0, WA_TOP,(scrn.barheight)+2,                        /* Setup Window Tags  */
  496.         WA_INNERWIDTH,MAPWINSIZE, WA_INNERHEIGHT,MAPWINSIZE,
  497.         WA_CUSTOMSCREEN,scrn, WA_SMARTREFRESH,TRUE,
  498.         WA_TITLE,mwtitle, WA_DRAGBAR,TRUE, WA_DEPTHGADGET,TRUE,
  499.         WA_GIMMEZEROZERO,TRUE, WA_IDCMP,MAPWINIDCMP,
  500.         WA_GADGETS,nulgad, WA_NEWLOOKMENUS,TRUE, TAG_END,NIL]
  501.  
  502.   mapwin:=OpenWindowTagList(NIL,tags)                                /* Open Map Window    */
  503.   IF mapwin=0                                                        /* If failed - report */
  504.      WriteF('Could not open map window !!\n')
  505.      RETURN 1
  506.   ENDIF
  507.   mapsig:=Shl(1,mapwin.userport.sigbit)                              /* Build signal mask  */
  508.  
  509.   menus:=[NM_TITLE, 0, 'Project',     0, 0, 0, 0,                  /* Setup New Menu stuff */
  510.            NM_ITEM, 0, 'New',       'N', 0, 0, MNUNEW,
  511.            NM_ITEM, 0, 'Open...',   'O', 0, 0, MNUOPEN,
  512.            NM_ITEM, 0, 'Save...',   'S', 0, 0, MNUSAVE,
  513.            NM_ITEM, 0, 'About',     'A', 0, 0, MNUABOUT,
  514.            NM_ITEM, 0, NM_BARLABEL,   0, 0, 0, 0,
  515.            NM_ITEM, 0, 'Quit',      'Q', 0, 0, 0,
  516.           NM_TITLE, 0, 'LineDefs',    0, 0, 0, 0,
  517.            NM_ITEM, 0, 'Open...',   'L', 0, 0, MNULNOPEN,
  518.            NM_ITEM, 0, 'Status',    'I', 0, 0, MNULNSTAT,
  519.             NM_END, 0, NIL,           0, 0, 0, 0]:newmenu
  520.  
  521.   visinfo:=GetVisualInfoA(scrn, [NIL])                           /* Attach menus to mapwin */
  522.   IF visinfo<>NIL
  523.     menustrip:=CreateMenusA(menus,[GTMN_FRONTPEN,1, TAG_END,NIL])
  524.     IF menustrip<>NIL
  525.       IF LayoutMenusA(menustrip, visinfo, [NIL])
  526.         IF SetMenuStrip(mapwin, menustrip)=FALSE
  527.           WriteF('Could not attach menus to map windows !!\n')
  528.           RETURN 1
  529.         ENDIF
  530.       ENDIF
  531.     ENDIF
  532.   ENDIF
  533.  
  534.   stat.mode  :=WE_MODE_ADD                                     /* Set intial gadget values */
  535.   stat.edtype:=0
  536.   stat.zoom  :=MINZOOM
  537.   stat.x     :=0
  538.   stat.y     :=0
  539.   stat.wx    :=0
  540.   stat.wy    :=0
  541.   stat.wid   :=0
  542.   stat.dep   :=0
  543.   stat.flr   :=-20
  544.   stat.ceil  :=20
  545.   stat.alt   :=0
  546.   stat.head  :=0
  547.   stat.size  :=512
  548.   stat.crad  :=0
  549.   stat.obid  :=0
  550.   stat.pass  :=FALSE
  551.  
  552.   congh:=guiinit('Control Panel',                                    /* Build Control GUI  */
  553.                   [ROWS,
  554.                     mcyc:=[CYCLE,{modehdlr},'Edit Mode',['Add','Delete','Edit',NIL],stat.mode],
  555.                     tcyc:=[CYCLE,{typehdlr},'Edit Type',['Objects','Col Boxes',NIL],stat.edtype],
  556.                     [COLS,
  557.                       zint:=[INTEGER,{zinthdlr},'Zoom',MINZOOM,4],
  558.                       zsld:=[SLIDE,{zslidehdlr},'',0,MINZOOM,MAXZOOM,MINZOOM,9,'']
  559.                     ],
  560.                     [COLS,
  561.                       mxint:=[INTEGER,{mxinthdlr},'MapX',stat.x,5],
  562.                       myint:=[INTEGER,{myinthdlr},'MapY',stat.y,5]
  563.                     ],
  564.                     [BAR],
  565.                     [COLS,
  566.                       wxint:=[INTEGER,{wxinthdlr},'ObjX',stat.wx,5],
  567.                       wyint:=[INTEGER,{wyinthdlr},'ObjY',stat.wy,5]
  568.                     ],
  569.                     [COLS,
  570.                       widint:=[INTEGER,{widinthdlr},'Wid ',stat.wid,5],
  571.                       depint:=[INTEGER,{depinthdlr},'Dep ',stat.dep,5]
  572.                     ],
  573.                     [COLS,
  574.                       flrint :=[INTEGER,{flrinthdlr} ,'Flr ',stat.flr, 5],
  575.                       ceilint:=[INTEGER,{ceilinthdlr},'Ceil',stat.ceil,5]
  576.                     ],
  577.                     [COLS,
  578.                       alt :=[INTEGER,{altinthdlr},'Alt ', stat.alt, 5],
  579.                       head:=[INTEGER,{headinthdlr},'Head',stat.head,5]
  580.                     ],
  581.                     [COLS,
  582.                       size:=[INTEGER,{sizeinthdlr},'Size',stat.size,5],
  583.                       crad:=[INTEGER,{cradinthdlr},'Rad ',stat.crad,5]
  584.                     ],
  585.                     [COLS,
  586.                       obid:=[INTEGER,{obidinthdlr},'ID #',stat.obid,5],
  587.                       pass:=[CHECK,{passchkhdlr},'Passable',stat.pass,TRUE]
  588.                     ],
  589.                     [COLS,
  590.                       obdf0 :=[STR,{obdfstrhdlr0},'DefA',s0,15,11],
  591.                       obdfb0:=[BUTTON,{obdfbuthdlr0},'>>']
  592.                     ],
  593.                     [COLS,
  594.                       obdf1 :=[STR,{obdfstrhdlr1},'DefB',s1,15,11],
  595.                       obdfb1:=[BUTTON,{obdfbuthdlr1},'>>']
  596.                     ],
  597.                     [COLS,
  598.                       obdf2 :=[STR,{obdfstrhdlr2},'DefC',s2,15,11],
  599.                       obdfb2:=[BUTTON,{obdfbuthdlr2},'>>']
  600.                     ],
  601.                     [COLS,
  602.                       obdf3 :=[STR,{obdfstrhdlr3},'DefD',s3,15,11],
  603.                       obdfb3:=[BUTTON,{obdfbuthdlr3},'>>']
  604.                     ],
  605.                     [BAR],
  606.                     [COLS,
  607.                       [BUTTON,{updbuthdlr},' Update '],
  608.                       [BUTTON,{clrbuthdlr},' Clear  ']
  609.                     ]
  610.                   ],stat,scrn,NIL,menus)
  611.  
  612.   IF congh=NIL
  613.     WriteF('Could not open Control Panel Window\n')
  614.     RETURN 1
  615.   ENDIF
  616.  
  617.   win:=congh.wnd
  618.   WindowLimits(win,win.width,win.height,win.width,win.height);
  619.  
  620.   stat.mcyc   :=mcyc       /* Store gadget E-List pointers */
  621.   stat.tcyc   :=tcyc
  622.   stat.zint   :=zint
  623.   stat.zsld   :=zsld
  624.   stat.mxint  :=mxint
  625.   stat.myint  :=myint
  626.  
  627.   stat.wxint  :=wxint
  628.   stat.wyint  :=wyint
  629.  
  630.   stat.widint :=widint
  631.   stat.depint :=depint
  632.   stat.flrint :=flrint
  633.   stat.ceilint:=ceilint
  634.  
  635.   stat.altint :=alt
  636.   stat.headint:=head
  637.   stat.sizeint:=size
  638.   stat.cradint:=crad
  639.   stat.obidint:=obid
  640.   stat.passchk:=pass
  641.  
  642.   stat.obdfstr[0]:=obdf0
  643.   stat.obdfstr[1]:=obdf1
  644.   stat.obdfstr[2]:=obdf2
  645.   stat.obdfstr[3]:=obdf3
  646.   stat.obdfbut[0]:=obdfb0
  647.   stat.obdfbut[1]:=obdfb1
  648.   stat.obdfbut[2]:=obdfb2
  649.   stat.obdfbut[3]:=obdfb3
  650.  
  651.   disablegadgets(0)
  652.  
  653.   filereq:=AllocAslRequest(ASL_FILEREQUEST,                           /* Map FileRequester */
  654.                      [ASL_HAIL,       'W.E. FileRequester',
  655.                       ASL_HEIGHT,     ASLHEIGHT,
  656.                       ASL_WIDTH,      ASLWIDTH,
  657.                       ASL_LEFTEDGE,   ASLLEFTEDGE,
  658.                       ASL_TOPEDGE,    ASLTOPEDGE,
  659.                       ASL_OKTEXT,     '  OK  ',
  660.                       ASL_CANCELTEXT, 'Cancel',
  661.                       ASL_FILE,       '',
  662.                       ASL_DIR,        '',
  663.                       ASL_WINDOW,     mapwin,
  664.                       ASL_FUNCFLAGS,  FILF_NEWIDCMP OR FILF_PATGAD,
  665.                       ASL_PATTERN,    '~(#?.info)',
  666.                       TAG_END,        NIL])
  667.  
  668.   linereq:=AllocAslRequest(ASL_FILEREQUEST,                      /* LineDef FileRequester  */
  669.                      [ASL_HAIL,       'W.E. FileRequester',
  670.                       ASL_HEIGHT,     ASLHEIGHT,
  671.                       ASL_WIDTH,      ASLWIDTH,
  672.                       ASL_LEFTEDGE,   ASLLEFTEDGE,
  673.                       ASL_TOPEDGE,    ASLTOPEDGE,
  674.                       ASL_OKTEXT,     '  OK  ',
  675.                       ASL_CANCELTEXT, 'Cancel',
  676.                       ASL_FILE,       '',
  677.                       ASL_DIR,        '',
  678.                       ASL_WINDOW,     mapwin,
  679.                       ASL_FUNCFLAGS,  FILF_NEWIDCMP OR FILF_PATGAD,
  680.                       ASL_PATTERN,    '~(#?.info)',
  681.                       TAG_END,        NIL])
  682.  
  683.   IF filereq=NIL OR linereq=NIL                                  /* Check Requester Allocated */
  684.     WriteF('Could not allocate file requester\n');
  685.     RETURN 1
  686.   ENDIF
  687. ENDPROC 0
  688.  
  689. /**********************************/
  690. /*** Draw in Background Imagery ***/
  691. /**********************************/
  692.  
  693. PROC drawbackdropwin()
  694.   DEF bdimage:image,bdidata,n,m,acr,dwn,x,y
  695.  
  696.   bdidata:=copyListToChip([
  697.     $FFFBCBFD,$FF7FFEFF,$C000FBFF,$FFFFFFFF,
  698.     $FDFFC000,$EFEEF7FD,$DFFBB7FF,$C000EF99,
  699.     $EDF3FF6A,$4BFFC000,$FFEDFFED,$FFA96DFF,
  700.     $C000FFF5,$6FFF7A97,$97FF8000,$FFFA9FFE,
  701.     $FF6BDFFF,$C000F7ED,$DFFFFFA7,$FFFFC000,
  702.     $FEBFFDF7,$F5DBFFFF,$C000FF75,$FFEFBFFF,
  703.     $FFFFC000,$FFEFBFFF,$7EFFFFFF,$C000DEFD,
  704.     $FBAADDFF,$FFFFC000,$BBFEBFFF,$EFFFFFFF,
  705.     $8000EF7D,$FFEBDFFF,$FFFFC000,$FDFFBBBE,
  706.     $FFFFFFFF,$C000FFBF,$F77DFFFF,$FEFF8000,
  707.     $FFF6AFEE,$FFFFFFFF,$C000FFDF,$7755FFFF,
  708.     $FDFF4000,$F7FDAEBB,$FFFFFFFF,$C000FFBE,
  709.     $DDF7FFFF,$FFFFC000,$FEFFFEBB,$FFFFBFF6,
  710.     $C000FFFF,$BB6EFFFF,$FFFFC000,$FD7ED6FD,
  711.     $FFFFFFFF,$C000FFEB,$7EDFFFFF,$FFFFC000,
  712.     $BFFFFBBF,$FDFFFFFF,$8000DFD6,$FEBFFFFF,
  713.     $FFFFC000,$FFDFFFEF,$FFFF7FFF,$4000BFFF,
  714.     $FFDDFFFF,$FFFFC000,$FED7D7F6,$FFFFFFBF,
  715.     $C000DFDD,$FFDB7DDF,$FEFFC000,$FFFBBEED,
  716.     $FFFFFFFF,$4000DFD7,$575EFFFF,$FDFFC000,
  717.     $BF7EFF75,$FBFFFFFF,$C000FBF5,$FFEFEFFF,
  718.     $FFFFC000,$EFFEFF77,$FFFFFFFF,$C000DEBF,
  719.     $DEFFFFFF,$FFFFC000,$FFFEFB7F,$FFFFFFFF,
  720.     $C000BDFB,$5DFDFFFF,$FFFF8000,$FFFDABEF,
  721.     $FFFFFFFF,$C000DFBE,$F7F5FFFF,$FFFFC000,
  722.     $BF7FDFEB,$FFFFFFFF,$C000BFFF,$FFEF7FFF,
  723.     $FFFB4000,$EBDFF7DF,$FFFFFFED,$C000AAFE,
  724.     $EFBFFFFF,$FFF74000,$5D5F5F76,$FFFFFFAA,
  725.     $8000F5D7,$7BFBFDFF,$FEEFC000,$D55DB6B7,
  726.     $FFFFEE9B,$C000FABE,$EBFEFFFF,$BAF7C000,
  727.     $F6DFB7BD,$7FFEFF5F,$40007BFB,$D6EFFFFB,
  728.     $FEFFC000,$BFF6DDD7,$F7EDFBFF,$8000DCFF,
  729.     $EE7FFFB7,$FF7E4000,$F3FFDFF7,$7E7F7DE9,
  730.     $4000EFF5,$FFF7FABE,$BBEFC000,$7FFFFFFB,
  731.     $FFDDEEAB,$00007FFB,$FB2DBEFC,$FED48000,
  732.     $FBF7ED7F,$EF7FEF5E,$C000FD6B,$FFFFFEEA,
  733.     $BFFF0000,$FC95FFFF,$EEFFBF7F,$C000DBFB,
  734.     $FB7FAFFF,$FFFFC000,$FDF7E5FF,$FAEFFBAB,
  735.     $8000EBEA,$9FFFFDDF,$F77F4000,$E7BDDFFF,
  736.     $F7BEFBFA,$C000F77D,$7FDFBBF5,$2FFFC000,
  737.     $FFF7FFFF,$FFFDE7EF,$C000F5EF,$FFFFDF76,
  738.     $FB9F8000,$ABFFFFFF,$BFEBFF7D,$8000BFFF,
  739.     $FFFFFFFF,$FFBBC000,$DFFFFFFF,$FFEDFBFF,
  740.     $C0003FFD,$FFFFBAD5,$F77BC000,$FFFFFFEF,
  741.     $FF7DFEDF,$C000FFFF,$FEFFFDFB,$FDD7C000,
  742.     $FFFFFFFF,$FF7EBB5B,$C000FFFD,$FFFFFEFF,
  743.     $7777C000,$FFFFFFFF,$EDDFFEEE,$C000FFFF,
  744.     $FFFFFF7B,$577DC000,$FFFFFDFF,$FFDD5EEF,
  745.     $C000FFFF,$DFEFFFBF,$EDDDC000,$FFFFFFFF,
  746.     $FD7FDBAE,$C0007FFF,$FFFDFFEE,$BBBFC000,
  747.     $FFFF7FFF,$BDFDF75F,$C000FFFF,$FFFFFFFF,
  748.     $BFFFC000,$7FFFFF77,$F77DDFD5,$C000FFFF,
  749.     $FFFFEFD7,$FBBBC000,$FEFFFFFF,$BD7FF76F,
  750.     $C0007BFF,$FFFFFFEB,$FFBFC000,$FFFFFFFF,
  751.     $EAF7DF7F,$C000F7FF,$FFFFDFDF,$BFFFC000,
  752.     $7FFFFFFF,$FBFEFFFF,$C000FFFF,$FFFFBFFB,
  753.     $EBEBC000,$FFF7FFFF,$F7FEBF7E,$C000FFFF,
  754.     $FFDFAFFA,$F6FD4000,$7FFFFFFF,$FFFB6B7D,
  755.     $C000F7FF,$FFFFFD7F,$F5FBC000,$FFFFFFFF,
  756.     $F7FEAFD7,$C000FFFF,$FFFFFFEF,$FD6FC000,
  757.     $7FFFFFDF,$FFFFFFDF,$C000FFBF,$FFFBFFDF,
  758.     $FD5FC000,$FEFFFFEE,$BFFFFDEF,$4000FFFF,
  759.     $FFBF7DFD,$FBBFC000,$FFFFFE6F,$FBFFFF5B,
  760.     $C000FFFF,$F9D5BFE6,$FDED4000,$FFFFE757,
  761.     $FEBFEFBB,$C000FFFF,$BABDF7AF,$FDDF4000,
  762.     $FFFEF5AB,$FD76FFEB,$8000FDFB,$FEFAFF5F,
  763.     $7DD6C000,$F7EF7FF6,$DABCFBEF,$C0007FB7,
  764.     $DF6FEEFB,$7FDFC000,$FFD7BDFF,$FFF6FFDF,
  765.     $C000FBFA,$AFE5EFFF,$DF7FC000,$EEEB7FFA,
  766.     $DFEFF57F,$4000392D,$FDBBFF1E,$FAFE8000,
  767.     /* Plane 1 */
  768.     $57F1C3B5,$6F7FFCEC,$000051BF,$5EFDFEDA,
  769.     $D9728000,$85C4E5D9,$8B7327C8,$80004608,
  770.     $E4E1FF20,$01224000,$5549BFC5,$5A884C95,
  771.     $000055A0,$45BE7203,$00200000,$56A00FFA,
  772.     $7D238545,$40008149,$5D5ED783,$20288000,
  773.     $541555E3,$F0C89515,$00002E20,$ADAF2FBA,
  774.     $48A08000,$A2450BEA,$5C61220A,$40000CA8,
  775.     $B00A9994,$89520000,$00B41BB5,$CE491449,
  776.     $00004228,$AA434922,$A2A20000,$28AD1114,
  777.     $E4480808,$8000A515,$22281289,$54550000,
  778.     $53A00544,$88522040,$00004A06,$22005288,
  779.     $888A0000,$A1B80411,$44425454,$4000250C,
  780.     $88A18895,$11024000,$A874A811,$2A4804A0,
  781.     $0000554B,$12044115,$12104000,$20280068,
  782.     $AAA0A8AA,$8000A942,$540D0015,$02220000,
  783.     $0D295115,$A8A05555,$00008484,$74152215,
  784.     $20800000,$2A869544,$88A20A2A,$00001255,
  785.     $56895514,$52908000,$140282A0,$204A080A,
  786.     $40008488,$AA820880,$A4084000,$2A911448,
  787.     $511510A2,$00008482,$02048840,$A80A4000,
  788.     $12145620,$212A0155,$000010A0,$B2458111,
  789.     $54408000,$42945622,$C4444A14,$4000841A,
  790.     $886B12AA,$91528000,$2894522A,$A4102452,
  791.     $000008A0,$08A88AAA,$92840000,$A9290145,
  792.     $50408851,$40000508,$42C08A2A,$45150000,
  793.     $942A9541,$20821041,$C0001A4A,$CB441554,
  794.     $AAAA0000,$C28AA287,$88422200,$80000044,
  795.     $451A5295,$54E64000,$18140A20,$29488100,
  796.     $0000A182,$11528022,$2E4B8000,$80092021,
  797.     $5509440A,$C000F03C,$82941054,$10A28000,
  798.     $A48F2128,$2A827E16,$000032D1,$C4468051,
  799.     $D46EC000,$1AF49882,$A28951B5,$0000C86F,
  800.     $CE250826,$F6340000,$A1F595E2,$223219C0,
  801.     $000067B4,$FF73501C,$A8A58000,$3EEBDBA9,
  802.     $1D484602,$00006BF3,$7225B6FC,$FC900000,
  803.     $79B3A43C,$0E2AC64C,$8000D442,$FFE96A62,
  804.     $3FBE0000,$F801DB64,$04EF1A77,$C00099FB,
  805.     $721104BD,$FFDD8000,$D5A3C044,$504FD103,
  806.     $000062E0,$09115085,$737B0000,$C31D844A,
  807.     $2514AB58,$C000E778,$090111A0,$26F74000,
  808.     $76A25294,$4AA803CF,$C000B1EA,$24228A20,
  809.     $E30D0000,$02C08954,$0A423939,$0000BF2A,
  810.     $A4012BD5,$A533C000,$9A401154,$A440D29D,
  811.     $80001928,$AAA41080,$A253C000,$60422002,
  812.     $9228B409,$40008A95,$54445850,$A8850000,
  813.     $52200229,$22341001,$80008888,$A8849456,
  814.     $22228000,$A2544552,$40895444,$00001522,
  815.     $10092A12,$02288000,$A05148A0,$A4900445,
  816.     $40005509,$0085350D,$48888000,$81444A20,
  817.     $A02A8104,$00002A29,$22882944,$110D8000,
  818.     $81441455,$0868A215,$0000AA2A,$41004955,
  819.     $16954000,$08808A22,$A2288A80,$8000A255,
  820.     $54110202,$D1110000,$080822A8,$102B2205,
  821.     $80002055,$54054A41,$552A8000,$52820151,
  822.     $40428A1D,$00000028,$AA2A0115,$1B528000,
  823.     $22952080,$9154556A,$80001242,$55551491,
  824.     $41014000,$A8A08808,$82D41274,$00008505,
  825.     $22820220,$24280000,$10A22914,$49504048,
  826.     $80004228,$84A2A816,$A1310000,$41455114,
  827.     $41240482,$80002A28,$0A82A545,$48428000,
  828.     $08854809,$D495750E,$8000A210,$A292BA85,
  829.     $A8054000,$54051444,$1655288A,$00002052,
  830.     $221E59A8,$D12A8000,$8AA94845,$71A15A01,
  831.     $40002102,$208116C4,$28880000,$94554205,
  832.     $DC16C511,$00004290,$1098A307,$688A0000,
  833.     $9444E002,$F864D581,$00004052,$ACD0561E,
  834.     $78800000,$21063EE4,$90186945,$400004A3,
  835.     $8A26C4F2,$7F870000,$52852956,$DFE4AB95,
  836.     $400023B0,$0DC0CABF,$CE7A8000,$084256D0,
  837.     $4FC6B06E,$00003809,$F93BFE1C,$F2BE0000,
  838.     /* Plane 2 */
  839.     $0A8A0948,$92124832,$40002248,$E5128965,
  840.     $24800000,$08080060,$14000162,$00008091,
  841.     $49028248,$48888000,$260044A8,$B1010000,
  842.     $000048C5,$0A440814,$12890000,$00101114,
  843.     $A6414010,$00002280,$88812004,$89020000,
  844.     $08084855,$25900040,$40004441,$13441049,
  845.     $220A0000,$09082011,$28A408A0,$00008041,
  846.     $01304480,$20008000,$1228350A,$82224144,
  847.     $00000441,$00809088,$08108000,$41182228,
  848.     $22012242,$00003002,$80008024,$00000000,
  849.     $05440A88,$25008915,$00002090,$40010022,
  850.     $20200000,$02010822,$11080100,$80009018,
  851.     $0104A220,$94240000,$24A25420,$80021000,
  852.     $40002010,$00481440,$41450000,$88448201,
  853.     $000A0400,$00000200,$28984940,$50888000,
  854.     $14521002,$80090000,$00000100,$C2208840,
  855.     $0A2A4000,$900A288A,$22082080,$000004A0,
  856.     $82000045,$00020000,$40040144,$89009210,
  857.     $80000D11,$5410200A,$00420000,$90400081,
  858.     $04404408,$00000204,$04082112,$00A28000,
  859.     $0820A440,$80005400,$00004104,$290A0444,
  860.     $01144000,$04208040,$91114041,$00001014,
  861.     $12264000,$24100000,$82408010,$09548148,
  862.     $80001012,$11412000,$08210000,$0C800008,
  863.     $02124104,$00009014,$A5A12080,$10404000,
  864.     $02080000,$8A294512,$40002091,$568A0000,
  865.     $00000000,$08044011,$2148AA49,$40002290,
  866.     $02008420,$01000000,$00011044,$00022422,
  867.     $00004444,$42212888,$80854000,$101004C2,
  868.     $00200814,$0000428A,$20284482,$22450000,
  869.     $10018200,$0010A400,$40005168,$108B2502,
  870.     $88B50000,$04024400,$00262202,$000010B4,
  871.     $8852A201,$08480000,$C2824A80,$08583080,
  872.     $40000841,$12A50002,$024A0000,$53356410,
  873.     $AA908800,$00001080,$00080848,$44448000,
  874.     $A245494A,$44452910,$00002809,$12300488,
  875.     $04550000,$90906481,$4052B548,$80000241,
  876.     $81040A4A,$01024000,$A9440411,$0000A22A,
  877.     $00008108,$90442912,$A4004000,$24280100,
  878.     $800812B2,$00008221,$240802C0,$01498000,
  879.     $A9440041,$10114404,$00000080,$89080C44,
  880.     $31120000,$A92A2001,$11008240,$80000400,
  881.     $015440A2,$08190000,$14892400,$0908A122,
  882.     $40002000,$00050000,$00010000,$8528A944,
  883.     $24515892,$80001000,$00109102,$01000000,
  884.     $00894882,$08582212,$8000A220,$02104000,
  885.     $04400000,$08011000,$0912A008,$800040A8,
  886.     $44A24040,$04410000,$0A020008,$09081008,
  887.     $00000050,$12026014,$81410000,$25010088,
  888.     $08410808,$40000084,$48208208,$22248000,
  889.     $28100100,$10A10002,$80000081,$14252228,
  890.     $2B480000,$22242000,$00010001,$00000800,
  891.     $05444484,$A2204000,$A0A28801,$0812804A,
  892.     $80000200,$00902080,$2A020000,$0028A404,
  893.     $00250828,$8000A482,$00808A60,$05850000,
  894.     $00002A2A,$2008A010,$00004892,$80000122,
  895.     $02420000,$0202224A,$24802828,$80001020,
  896.     $08080088,$80800000,$42088041,$24220211,
  897.     $000000A2,$22080000,$40404000,$14100841,
  898.     $224C0905,$00008082,$80100802,$A0088000,
  899.     $22102282,$A5202A44,$40000804,$0800506A,
  900.     $80120000,$4050408A,$09005140,$00008900,
  901.     $84242091,$00050000,$20041002,$A2443410,
  902.     $00008450,$81500800,$81400000,$01000402,
  903.     $A4AA0802,$80002805,$20204400,$C1100000,
  904.     $00904509,$21122942,$00009001,$10200808,
  905.     $10048000,$024A4942,$42A4D288,$00002000,
  906.     $040A0820,$01128000,$899290A1,$64924C40,
  907.     $00000040,$06800544,$91150000,$A4092022,
  908.     $92094450,$00001120,$94908808,$20448000])
  909.   
  910.   bdimage:=[0, 0,             /* LeftEdge, TopEdge     */
  911.           66, 112, 3,         /* Width, Height, Depth  */
  912.           bdidata,            /* ImageData             */
  913.           $0007, $0000,       /* PlanePick, PlaneOnOff */
  914.           NIL                 /* NextImage             */
  915.           ]:image
  916.  
  917.   acr:=Div(bdwin.width,66)
  918.   dwn:=Div(bdwin.height,111)
  919.   FOR n:=0 TO acr
  920.     FOR m:=0 TO dwn
  921.       x:=Mul(n,66)
  922.       y:=Mul(m,111)
  923.       DrawImage(bdwin.rport, bdimage, x ,y)
  924.     ENDFOR
  925.   ENDFOR
  926.  
  927.   Dispose(bdidata)
  928. ENDPROC
  929.  
  930. PROC copyListToChip(data)
  931.   DEF size, mem
  932.   size:=ListLen(data)*SIZEOF LONG
  933.   mem:=NewM(size, MEMF_CHIP)
  934.   CopyMemQuick(data, mem, size)
  935. ENDPROC mem
  936.  
  937. /*************************************/
  938. /*** Load Object Definitions Array ***/
  939. /*************************************/
  940.  
  941. /* The error flag 1=output error using WriteF & return error
  942.                   0=just return error
  943.  
  944.    Returns 0 on success, otherwise 1 */
  945.  
  946. PROC loadobjdefs(error)
  947.   DEF handle,len,size,hdr:obdfheader,ret=1
  948.   DEF ptr:PTR TO objdef
  949.  
  950.   handle:=Open('ObjDef.Data',MODE_OLDFILE)                        /* Attempt to Open File    */
  951.   IF handle<>NIL                                                  /* If opened O.K.          */
  952.     len:=Read(handle,hdr,SIZEOF obdfheader)                       /* Attempt to Read Header  */
  953.     IF len=SIZEOF obdfheader                                      /* If read O.K.            */
  954.       IF hdr.magic=OBJDEFMAGIC                                    /* and is of Correct Type  */
  955.         IF (hdr.count>0) AND (hdr.count<1001)                     /* Check ObjDef Count      */
  956.           IF stat.defptr<>NIL THEN Dispose(stat.defptr)           /* Free old ObjDef Data    */
  957.           stat.defcount:=hdr.count                                /* Store New ObjDef Count  */
  958.           size:=Mul(hdr.count,SIZEOF objdef)                      /* Calc RAM for ObjDefs    */
  959.           stat.defptr:=New(size)                                  /* Alloc RAM for ObjDefs   */
  960.           len:=Read(handle,stat.defptr,size)                      /* Attempt to Read ObjDefs */
  961.           IF len=size                                             /* If read O.K.            */
  962.             builddeflist()                                        /* Build defs exec list    */
  963.             ret:=0                                                /* Set Success Flag        */
  964.           ELSE
  965.             IF error=1 THEN WriteF('The file is Truncated\n')     /* File is Truncated       */
  966.             Dispose(stat.defptr)                                  /* Cleanup ObjDef Details  */
  967.             stat.defcount:=NIL
  968.             stat.defptr:=NIL
  969.           ENDIF
  970.         ELSE
  971.           IF error=1 THEN WriteF('ObjDef Count out of Bounds\n')  /* ObjDef Count Wrong      */
  972.         ENDIF
  973.       ELSE
  974.         IF error=1 THEN WriteF('File is not an ObjDef file\n')    /* File Type In-correct    */
  975.       ENDIF
  976.     ELSE
  977.       IF error=1 THEN WriteF('Could not Read file Header\n')      /* Could not read header   */
  978.     ENDIF
  979.     Close(handle)
  980.   ELSE
  981.     IF error=1 THEN WriteF('Failed to Open ObjDef file\n')        /* Could Not Open File     */
  982.   ENDIF
  983. ENDPROC ret
  984.  
  985. /*******************************************************/
  986. /*** Convert ObjDef Array to ExecList and Free Array ***/
  987. /*******************************************************/
  988.  
  989. PROC builddeflist()
  990.   DEF n,m,di:PTR TO defitem
  991.  
  992.   IF stat.deflist=NIL                             /* If no current exec list header */
  993.     stat.deflist:=newlist()                       /* Build new blank list           */
  994.   ELSE
  995.     freedefnodes()                                /* Otherwise kill contents        */
  996.   ENDIF
  997.  
  998.   FOR n:=0 TO stat.defcount-1                     /* Loop throgh objdef array       */
  999.     di:=New(SIZEOF defitem)                       /* Alloc RAM for new defitem node */
  1000.     FOR m:=0 TO 15                                /* Copy name from objdef->defitem */
  1001.       di.name[m]:=stat.defptr[n].name[m]
  1002.     ENDFOR
  1003.     di.id:=stat.defptr[n].id                      /* Copy ID from objdef->defitem   */
  1004.     newnode(di.node,di.name,0,0)                  /* Initialise defitem's node      */
  1005.     Enqueue(stat.deflist,di.node)                 /* Add node to current list end   */
  1006.   ENDFOR
  1007.   Dispose(stat.defptr)                            /* Free objdef array (not needed) */
  1008.   stat.defptr:=NIL                                /* Clear objdef array base ptr    */
  1009. ENDPROC
  1010.  
  1011. /*** Free Contents of DefItem Exec List ***/
  1012.  
  1013. PROC freedefnodes()
  1014.   DEF di:PTR TO defitem,next:PTR TO defitem
  1015.  
  1016.   di:=stat.deflist.head
  1017.   WHILE di.node.succ<>NIL
  1018.     next:=di.node.succ
  1019.     Remove(di.node)
  1020.     Dispose(di)
  1021.     di:=next
  1022.   ENDWHILE
  1023. ENDPROC
  1024.  
  1025. /*****************************/
  1026. /**** Init Misc Resources ****/
  1027. /*****************************/
  1028.  
  1029. /* Returns 0 on success */
  1030.  
  1031. PROC initmisc()
  1032.   tantab:=[$00000004,$00000008,$0000000D,$00000011,
  1033.            $00000016,$0000001A,$0000001F,$00000023,
  1034.            $00000028,$0000002D,$00000031,$00000036,
  1035.            $0000003B,$0000003F,$00000044,$00000049,
  1036.            $0000004E,$00000053,$00000058,$0000005D,
  1037.            $00000062,$00000067,$0000006C,$00000071,
  1038.            $00000077,$0000007C,$00000082,$00000088,
  1039.            $0000008D,$00000093,$00000099,$0000009F,
  1040.            $000000A6,$000000AC,$000000B3,$000000B9,
  1041.            $000000C0,$000000C8,$000000CF,$000000D6,
  1042.            $000000DE,$000000E6,$000000EE,$000000F7,
  1043.            $000000FF,$00000109,$00000112,$0000011C,
  1044.            $00000126,$00000131,$0000013C,$00000147,
  1045.            $00000153,$00000160,$0000016D,$0000017B,
  1046.            $0000018A,$00000199,$000001AA,$000001BB,
  1047.            $000001CD,$000001E1,$000001F6,$0000020C,
  1048.            $00000224,$0000023E,$0000025B,$00000279,
  1049.            $0000029A,$000002BF,$000002E7,$00000313,
  1050.            $00000345,$0000037C,$000003BB,$00000402,
  1051.            $00000454,$000004B4,$00000525,$000005AB,
  1052.            $00000650,$0000071D,$00000824,$00000983,
  1053.            $00000B6E,$00000E4C,$00001314,$00001CA2,
  1054.            $0000394A]
  1055. ENDPROC 0
  1056.  
  1057. /*****************************/
  1058. /**** Cleanup before Exit ****/
  1059. /*****************************/
  1060.  
  1061. PROC cleanup()
  1062.    IF linereq<>NIL             THEN FreeAslRequest(linereq)
  1063.    IF filereq<>NIL             THEN FreeAslRequest(filereq)
  1064.    IF congh<>NIL               THEN cleangui(congh)
  1065.    IF mapwin.menustrip<>NIL    THEN ClearMenuStrip(mapwin)
  1066.    IF menustrip<>NIL           THEN FreeMenus(menustrip)
  1067.    IF visinfo<>NIL             THEN FreeVisualInfo(visinfo)
  1068.    IF mapwin<>NIL       THEN CloseWindow(mapwin)
  1069.    IF bdwin<>NIL        THEN CloseWindow(bdwin)
  1070.    IF scrn<>NIL         THEN CloseScreen(scrn)
  1071.    IF font<>NIL         THEN CloseFont(font)
  1072.    IF aslbase<>NIL      THEN CloseLibrary(aslbase)
  1073.    IF gadtoolsbase<>NIL THEN CloseLibrary(gadtoolsbase)
  1074.    IF diskfontbase<>NIL THEN CloseLibrary(diskfontbase)
  1075. ENDPROC
  1076.  
  1077. /*************************************************/
  1078. /**** Wait on both ports for interface events ****/
  1079. /*************************************************/
  1080.  
  1081. PROC waitevent()
  1082.   DEF sig,ret=-1
  1083.  
  1084.   drawall()                                                       /* Do Initial Re-Draw     */
  1085.  
  1086.   WHILE ret<>0                                                    /* Loop until return=0    */
  1087.     sig:=Wait(mapsig OR congh.sig)                                /* Wait on both ports     */
  1088.     IF (sig AND mapsig)    THEN ret:=mapevent()                   /* Handle MapWin events   */
  1089.     IF (sig AND congh.sig) THEN ret:=conevent()                   /* Handle EasyGUI events  */
  1090.  
  1091.     IF ret=0                                                      /* Verify Exit */
  1092.       ret:=butrequest('W.E. Request','Quit, Are you sure ?',' Quit |Cancel')
  1093.       IF ret=0 THEN ret:=-1 ELSE ret:=0
  1094.     ENDIF
  1095.  
  1096.   ENDWHILE
  1097. ENDPROC
  1098.  
  1099. /**********************************/
  1100. /**** Handle Map Window Events ****/
  1101. /**********************************/
  1102.  
  1103. /* Return >= 0 to force exit
  1104.  
  1105. NOTE - IDCMP_MOUSEBUTTONS msg.code = SELECTDOWN,SELECTUP,MENUDOWN or MENUUP
  1106.        There are also middle button events.
  1107.  
  1108. This routine loops until all messages at port are dealt with
  1109. */
  1110.  
  1111. PROC mapevent()
  1112.    DEF ret=-1,class,code, iaddr,msg=NIL:PTR TO intuimessage
  1113.    DEF gad=NIL:PTR TO gadget,mnu:PTR TO menuitem
  1114.  
  1115.    msg:=GetMsg(mapwin.userport)                                /** Get 1st message & store **/
  1116.    WHILE msg<>NIL
  1117.       class:=msg.class                                         /*     important details     */
  1118.       code :=msg.code
  1119.       iaddr:=msg.iaddress
  1120.       ReplyMsg(msg)                                            /**     Reply to Sender     **/
  1121.  
  1122.       SELECT class
  1123.       CASE IDCMP_GADGETDOWN                                    /** Handle Gadget Dn Events **/
  1124.          gad:=iaddr                                            /* Get Gadget Pointer        */
  1125.          stat.actscroll:=gad                                   /* Set Active Scroll Gadget  */
  1126.       CASE IDCMP_GADGETUP                                      /** Handle Gadget Up Events **/
  1127.          gad:=iaddr                                            /* Get Gadget Pointer        */
  1128.          stat.actscroll:=NIL                                   /* Clr Active Scroll Gadget  */
  1129.          SELECT gad                                            /* Is it the Vert Scroller?  */
  1130.          CASE vscrl                                            /* Update Y Co-ord Gadgets   */
  1131.             getvscroller()                                     /* Is it the Horz Scroller?  */
  1132.          CASE hscrl                                            /* Update X Co-ord Gadgets   */
  1133.             gethscroller()
  1134.          ENDSELECT
  1135.       CASE IDCMP_MOUSEBUTTONS                                  /** Get Mouse Button Events **/
  1136.          clickmodehdlr(code)
  1137.       CASE IDCMP_INTUITICKS                                    /** Handle Intuitick Events **/
  1138.          IF stat.mouse THEN handledrag()                       /* If mouse down draw stuff  */
  1139.          gad:=stat.actscroll                                   /*  Get Current Active Gad   */
  1140.          SELECT gad
  1141.          CASE vscrl                                            /* If Vertical Update Y Gadg */
  1142.             getvscroller()
  1143.          CASE hscrl                                            /* If Horiz updates X Gadget */
  1144.             gethscroller()
  1145.          ENDSELECT
  1146.       CASE IDCMP_MENUPICK                                      /**    Handle Menu Event    **/
  1147.          code:=UNSIGNED(code)
  1148.          WHILE (code<>MENUNULL) AND (ret<>0)                   /*  Loop throgh menu events  */
  1149.            mnu:=ItemAddress(menustrip,code)                    /*  Get address of menuitem  */
  1150.            code:=UNSIGNED(mnu.nextselect)                      /*  Get next menu selection  */
  1151.            ret:=GTMENUITEM_USERDATA(mnu)                       /*  Get menuitems user data  */
  1152.            IF ret<>0 THEN menuhandler(ret)                     /*  Call menu event handler  */
  1153.          ENDWHILE                                              /* Loop until no more events */
  1154.       ENDSELECT
  1155.       msg:=GetMsg(mapwin.userport)                             /** Get Next message if any **/
  1156.    ENDWHILE
  1157. ENDPROC ret
  1158.  
  1159. /*******************************************/
  1160. /**** Handle Drawing Mouse Drag Details ****/
  1161. /*******************************************/
  1162.  
  1163. PROC handledrag()
  1164.   DEF x,y,dx,dy
  1165.  
  1166.   IF stat.mousecount THEN drawdrag()
  1167.   x:=mapwin.gzzmousex
  1168.   y:=mapwin.gzzmousey
  1169.   IF (x>=0) AND (x<MAPWINSIZE) AND (y>=0) AND (y<MAPWINSIZE)
  1170.     stat.mouseex:=x
  1171.     stat.mouseey:=y
  1172.     dx:=Shr(stat.mousesx-x,1)
  1173.     dy:=Shr(stat.mousesy-y,1)
  1174.     IF dx<0 THEN dx:=0-dx
  1175.     IF dy<0 THEN dy:=0-dy
  1176.     IF dx+dy>0
  1177.       drawdrag()
  1178.       stat.mousecount:=1
  1179.     ENDIF
  1180.   ENDIF
  1181. ENDPROC
  1182.  
  1183. /***************************************/
  1184. /**** Do XOR drawing during drag op ****/
  1185. /***************************************/
  1186.  
  1187. PROC drawdrag()
  1188.   DEF oldrast,mode
  1189.   DEF wobj:PTR TO wobject, col:PTR TO colarea
  1190.   DEF x1,y1,x2,y2,t,s,type
  1191.  
  1192.   mode:=stat.mode
  1193.   oldrast:= stdrast                                              /* Store current rastport  */
  1194.   stdrast:= mapwin.rport                                         /* Set rastport to mapwin  */
  1195.   SetDrMd(stdrast,RP_COMPLEMENT)                                 /* Set complement drawmode */
  1196.  
  1197.   IF stat.edtype
  1198.     IF stat.mode=WE_MODE_ADD  THEN type:=1
  1199.     IF stat.mode=WE_MODE_EDIT THEN type:=3
  1200.     IF stat.mode=WE_MODE_DEL  THEN type:=1
  1201.   ELSE
  1202.     IF stat.mode=WE_MODE_ADD  THEN type:=0
  1203.     IF stat.mode=WE_MODE_EDIT THEN type:=2
  1204.     IF stat.mode=WE_MODE_DEL  THEN type:=1
  1205.   ENDIF
  1206.  
  1207.   SELECT type
  1208.   CASE 0
  1209.     Line(stat.mousesx,stat.mousesy,stat.mouseex,stat.mouseey,ORANGE)           /* Draw line */
  1210.   CASE 1
  1211.     Line(stat.mousesx,stat.mousesy,stat.mouseex,stat.mousesy,ORANGE)           /* Draw box  */
  1212.     Line(stat.mouseex,stat.mousesy,stat.mouseex,stat.mouseey,ORANGE)
  1213.     Line(stat.mousesx,stat.mouseey,stat.mouseex,stat.mouseey,ORANGE)
  1214.     Line(stat.mousesx,stat.mousesy,stat.mousesx,stat.mouseey,ORANGE)
  1215.   CASE 2
  1216.     wobj:=stat.actwobj
  1217.     IF wobj.radius=0                                     /* Base map size & Color on radius */
  1218.       s:=4                                               /* Non collsion object are 4 rad.  */
  1219.     ELSEIF wobj.size=0
  1220.       s:=wobj.radius
  1221.     ELSE
  1222.       s:=wobj.radius
  1223.     ENDIF
  1224.     t:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE)           /* Calculate Pixel Divisor  */
  1225.     s:=Div(Shl(s,9),t)                                          /* Calculate size           */
  1226.     IF s>MAPWINSIZE THEN s:=MAPWINSIZE                          /* Limit size to MAPWINSIZE */
  1227.     x2:=stat.mouseex+s                                          /* Calculate Box Dimensions */
  1228.     y2:=stat.mouseey+s
  1229.     x1:=stat.mouseex-s
  1230.     y1:=stat.mouseey-s
  1231.     IF (x2>=0) AND (y2>=0) AND (x1<MAPWINSIZE) AND (y1<MAPWINSIZE)  /* If in window draw it */
  1232.       Line(x1,y1,x2,y2,ORANGE)
  1233.       Line(x1,y2,x2,y1,ORANGE)
  1234.     ENDIF
  1235.   CASE 3
  1236.     col:=stat.actcol
  1237.     x1:=stat.mouseex
  1238.     y1:=stat.mouseey
  1239.     IF (x1>=0) AND (y1>=0) AND (x1<MAPWINSIZE) AND (y1<MAPWINSIZE)  /* If in window draw it */
  1240.       t:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE)          /* Calculate Pixel Divisor */
  1241.       x2:=(Div(Shl(col.width,9),t))+x1                           /* Calc on screen width &  */
  1242.       y2:=(Div(Shl(col.depth,9),t))+y1                           /* depth                   */
  1243.       Line(x1,y1,x2,y1,ORANGE)                                   /* Draw draggable box      */
  1244.       Line(x2,y1,x2,y2,ORANGE)
  1245.       Line(x2,y2,x1,y2,ORANGE)
  1246.       Line(x1,y2,x1,y1,ORANGE)
  1247.     ENDIF
  1248.   ENDSELECT
  1249.   SetDrMd(stdrast,RP_JAM1)                                       /* Restore old draw mode   */
  1250.   stdrast:=oldrast                                               /* Restore old rastport    */
  1251.   stat.mousecount:=0                                             /* Clear mouse draw flag   */
  1252. ENDPROC
  1253.  
  1254. /********************************************/
  1255. /*** Handle Map Window Mouse Click Events ***/
  1256. /********************************************/
  1257.  
  1258. PROC clickmodehdlr(code)
  1259.   DEF x,y,mode
  1260.  
  1261.   mode:=stat.mode                                               /* Get current editor mode   */
  1262.  
  1263.   SELECT code
  1264.   CASE SELECTDOWN                                               /* Handle mouse but. down    */
  1265.     x:=mapwin.gzzmousex                                         /* Get Co-ords rel.to GZZwin */
  1266.     y:=mapwin.gzzmousey                                         /* Only store if in window   */
  1267.     IF (x>=0) AND (x<MAPWINSIZE) AND (y>=0) AND (y<MAPWINSIZE)
  1268.       stat.mouse:=1                                             /* Set drag op started flag  */
  1269.       stat.mousesx:=x                                           /* Store Co-ords as down pos */
  1270.       stat.mousesy:=y
  1271.       stat.mouseex:=x
  1272.       stat.mouseey:=y
  1273.       stat.mousecount:=0                                        /* Init drag draw statusflag */
  1274.       SELECT mode
  1275.       CASE WE_MODE_EDIT                                         /* Call Edit Mode handler    */
  1276.         editdownclick()
  1277.       ENDSELECT
  1278.     ELSE
  1279.       stat.mouse:=0                                             /* Clear draw op flag        */
  1280.     ENDIF
  1281.   CASE SELECTUP                                                 /* Handle mouse but. release */
  1282.     IF stat.mousecount THEN drawdrag()                          /* Undraw drag box if any    */
  1283.     SELECT mode
  1284.     CASE WE_MODE_ADD                                            /* Call Add Mode Clk handler */
  1285.       addupclick()
  1286.     CASE WE_MODE_DEL                                            /* Call Del Mode Clk handler */
  1287.       delupclick()
  1288.     CASE WE_MODE_EDIT                                           /* Call Edit Mode handler    */
  1289.       editupclick()
  1290.     ENDSELECT
  1291.     stat.mouse:=0                                               /* Clear mouse drag op flag  */
  1292.   ENDSELECT
  1293. ENDPROC
  1294.  
  1295. /*****************************************/
  1296. /**** Handle add mode mouse up/events ****/
  1297. /*****************************************/
  1298.  
  1299. PROC addupclick()
  1300.   DEF x,y,x1,y1,x2,y2,t
  1301.   DEF witem:PTR TO wobitem,citem:PTR TO colitem
  1302.  
  1303.   x:=mapwin.gzzmousex                                         /* Get Co-ords rel.to GZZwin */
  1304.   y:=mapwin.gzzmousey
  1305.   IF (x>=0) AND (x<MAPWINSIZE) AND (y>=0) AND (y<MAPWINSIZE)  /* If inside GZZ window      */
  1306.     x2,y2:=screen2map(x,y)                                    /* Map Co-ords of Up Event   */
  1307.  
  1308.     IF stat.edtype
  1309.       x1,y1:=screen2map(stat.mousesx,stat.mousesy)            /* Map Co-ords of Down Event */
  1310.       IF x2<x1                                                /* Ensure co-ords ascending  */
  1311.         t:=x1
  1312.         x1:=x2
  1313.         x2:=t
  1314.       ENDIF
  1315.       IF y2<y1
  1316.         t:=y1
  1317.         y1:=y2
  1318.         y2:=t
  1319.       ENDIF
  1320.       IF (x2<=(x1+1)) OR (y2<=(y1+1)) THEN RETURN
  1321.       stat.wx:=x1
  1322.       stat.wy:=y1
  1323.       stat.wid:=x2-x1                                         /* Calculate width & depth   */
  1324.       stat.dep:=y2-y1
  1325.       setinteger(congh,stat.widint,stat.wid)                  /* Update Width/Depth in GUI */
  1326.       setinteger(congh,stat.depint,stat.dep)
  1327.       citem:=New(SIZEOF colitem)
  1328.       newnode(citem.node,NIL,0,0)
  1329.       Enqueue(stat.collist,citem.node)
  1330.       gui2col(citem.col)
  1331.       SetStdRast(mapwin.rport)
  1332.       coldraw(citem.col,0,0)
  1333.     ELSE
  1334.       IF stat.obdfid[0]=NIL                                   /* Check Gadget Settings     */
  1335.         butrequest('Warning','No Primary ObjDef Specified',' OK ')
  1336.         RETURN
  1337.       ENDIF
  1338.       stat.wx:=x2                                             /* Set wobject X,Y Co-ords   */
  1339.       stat.wy:=y2
  1340.       setinteger(congh,stat.wxint,stat.wx)                    /* Reflect Co-ords in GUI    */
  1341.       setinteger(congh,stat.wyint,stat.wy)
  1342.       witem:=New(SIZEOF wobitem)                              /* Allocate RAM for wobject  */
  1343.       newnode(witem.node,NIL,0,0)                             /* Initialise node structure */
  1344.       Enqueue(stat.woblist,witem.node)                        /* Add wobject to exec list  */
  1345.       gui2wobj(witem.wob)                                     /* Copy GUI to WObject       */
  1346.       SetStdRast(mapwin.rport)                                /* Setup for Mapwin drawing  */
  1347.       wobjdraw(witem.wob,0,0)                                   /* Draw in new object        */
  1348.     ENDIF
  1349.     setinteger(congh,stat.wxint,stat.wx)                      /* Reflect Co-ords in GUI    */
  1350.     setinteger(congh,stat.wyint,stat.wy)
  1351.   ENDIF
  1352. ENDPROC
  1353.  
  1354. /*************************************************/
  1355. /**** Handle delete mode mouse up/down events ****/
  1356. /*************************************************/
  1357.  
  1358. PROC delupclick()
  1359.   DEF ret,next,x,y,wobx,woby
  1360.   DEF item:PTR TO wobitem, citem:PTR TO colitem
  1361.  
  1362.   IF stat.mouse                                                 /* Ignore if not drag op    */
  1363.     x:=mapwin.gzzmousex
  1364.     y:=mapwin.gzzmousey
  1365.     IF (x>=0) AND (x<MAPWINSIZE) AND (y>=0) AND (y<MAPWINSIZE)  /* If inside GZZ window     */
  1366.       wobx,woby:=screen2map(x,y)
  1367.       x,y:=screen2map(stat.mousesx,stat.mousesy)
  1368.       IF stat.edtype
  1369.         ret:=groupselectclb(wobx,woby,x,y)
  1370.         IF ret THEN ret:=butrequest('W.E. Request','Delete Collison Box(s) ?','Delete|Cancel')
  1371.         IF ret                                                  /* Check Deletion is O.K.   */
  1372.           citem:=stat.collist.head                              /* Get Start of colitem List*/
  1373.           WHILE citem.node.succ<>NIL                            /* If Valid colitem         */
  1374.             next:=citem.node.succ                               /* Store ptr to next colitem*/
  1375.             IF citem.select                                     /* If item selected then .. */
  1376.               IF citem.col=stat.actcol THEN stat.actcol:=NIL    /* Clear actcol  if deleted */
  1377.               Remove(citem.node)                                /* Remove colbox From List  */
  1378.               Dispose(citem.node)                               /* Dispose of Items Memory  */
  1379.             ENDIF
  1380.             citem:=next
  1381.           ENDWHILE
  1382.         ENDIF
  1383.         IF stat.actcol<>NIL
  1384.           col2gui(stat.actcol)                                  /* Update GUI as required   */
  1385.         ELSE
  1386.           clrbuthdlr(0)
  1387.         ENDIF
  1388.       ELSE
  1389.         ret:=groupselectwob(wobx,woby,x,y)
  1390.         IF ret THEN ret:=butrequest('W.E. Request','Delete Object(s) ?','Delete|Cancel')
  1391.         IF ret                                                  /* Check Deletion is O.K.   */
  1392.           item:=stat.woblist.head                               /* Get Start of wobitem List*/
  1393.           WHILE item.node.succ<>NIL                             /* If Valid wobitem         */
  1394.             next:=item.node.succ                                /* Store ptr to next wobitem*/
  1395.             IF item.select                                      /* If item selected then .. */
  1396.               IF item.wob=stat.actwobj THEN stat.actwobj:=NIL   /* Clear actwobj if deleted */
  1397.               Remove(item.node)                                 /* Remove Object From List  */
  1398.               Dispose(item.node)                                /* Dispose of Items Memory  */
  1399.             ENDIF
  1400.             item:=next
  1401.           ENDWHILE
  1402.         ENDIF
  1403.         IF stat.actwobj<>NIL
  1404.           wobj2gui(stat.actwobj)                                /* Update GUI as required   */
  1405.         ELSE
  1406.           clrbuthdlr(0)
  1407.         ENDIF
  1408.       ENDIF
  1409.       drawall()                                                 /* Update map display etc.  */
  1410.     ENDIF
  1411.   ENDIF
  1412. ENDPROC
  1413.  
  1414. /***********************************************/
  1415. /**** Handle edit mode mouse up/down events ****/
  1416. /***********************************************/
  1417.  
  1418. PROC editdownclick()
  1419.   DEF x,y,wobj:PTR TO wobject,col:PTR TO colarea
  1420.  
  1421.   x,y:=screen2map(stat.mousesx,stat.mousesy)                  /* Get mouse down coords    */
  1422.  
  1423.   IF stat.edtype                                              /*** Handle ColArea Edit  ***/
  1424.     col:=findcolcoord(x,y)                                    /* Find colarea at coords   */
  1425.     IF col<>NIL                                               /* If object found then     */
  1426.       col2gui(col)                                            /* Copy to GUI & Highlight  */
  1427.     ELSE
  1428.       stat.mouse:=0                                           /* Otherwise cancel drag op */
  1429.     ENDIF
  1430.   ELSE                                                        /*** Handle Wobject Edit  ***/
  1431.     wobj:=findwobjcoord(x,y)                                  /* Find object at coords    */
  1432.     IF wobj<>NIL                                              /* If object found then     */
  1433.       wobj2gui(wobj)                                          /* Copy to GUI & Highlight  */
  1434.     ELSE
  1435.       stat.mouse:=0                                           /* Otherwise cancel drag op */
  1436.     ENDIF
  1437.   ENDIF
  1438. ENDPROC
  1439.  
  1440. PROC editupclick()
  1441.   DEF x,y,dx,dy,wobj:PTR TO wobject,col:PTR TO colarea
  1442.  
  1443.   x:=mapwin.gzzmousex                                         /* Get current mouse coords */
  1444.   y:=mapwin.gzzmousey
  1445.   IF (x>=0) AND (x<MAPWINSIZE) AND (y>=0) AND (y<MAPWINSIZE)  /* Ensure inside GZZ window */
  1446.     dx:=Shr(stat.mousesx-x,1)                                 /* Determine distance moved */
  1447.     dy:=Shr(stat.mousesy-y,1)
  1448.     IF dx<0 THEN dx:=0-dx
  1449.     IF dy<0 THEN dy:=0-dy
  1450.  
  1451.     IF stat.edtype
  1452.       col:=NIL
  1453.       IF stat.mouse AND (dx+dy<>0)                            /* If drag op then update   */
  1454.         x,y:=screen2map(x,y)                                  /* ColArea to release pos   */
  1455.         col:=stat.actcol
  1456.         col.x:=x
  1457.         col.y:=y
  1458.         col2gui(col)
  1459.         drawall()
  1460.       ELSE                                                    /* If not drag op then find */
  1461.         x,y:=screen2map(x,y)                                  /* colarea clicked up over  */
  1462.         col:=findcolcoord(x,y)
  1463.       ENDIF
  1464.  
  1465.     ELSE
  1466.       wobj:=NIL
  1467.       IF stat.mouse AND (dx+dy<>0)                            /* If drag op then update   */
  1468.         x,y:=screen2map(x,y)                                  /* Wobject to release pos   */
  1469.         wobj:=stat.actwobj
  1470.         wobj.x:=x
  1471.         wobj.y:=y
  1472.         wobj2gui(wobj)
  1473.         drawall()
  1474.       ELSE                                                    /* If not drag op then find */
  1475.         x,y:=screen2map(x,y)                                  /* object clicked up over   */
  1476.         wobj:=findwobjcoord(x,y)
  1477.       ENDIF
  1478.       IF wobj<>NIL THEN wobj2gui(wobj)                        /* Update object found/moved*/
  1479.     ENDIF
  1480.   ENDIF
  1481. ENDPROC
  1482.  
  1483. /***********************************************/
  1484. /**** Convert Screen Co-ords to map Co-ords ****/
  1485. /***********************************************/
  1486.  
  1487. PROC screen2map(scrx,scry)
  1488.   DEF mult,mapx,mapy
  1489.   mult:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE)      /* Calculate Map Co-ords */
  1490.   mapx:=Shr(Mul(mult,scrx),9)+stat.x
  1491.   mapy:=Shr(Mul(mult,scry),9)+stat.y
  1492. ENDPROC mapx,mapy
  1493.  
  1494. /****************************/
  1495. /**** Handle Menu Events ****/
  1496. /****************************/
  1497.  
  1498. /* Not needed to handle quit (0) menu events */
  1499.  
  1500. PROC menuhandler(event)
  1501.   SELECT event
  1502.   CASE MNUNEW
  1503.     newmap()
  1504.   CASE MNUOPEN
  1505.     loadrequest()
  1506.   CASE MNUSAVE
  1507.     saverequest()
  1508.   CASE MNUABOUT
  1509.     butrequest('About W.E.',abouttitle,' OK ')
  1510.   CASE MNULNOPEN
  1511.     loadlinerequest()
  1512.   CASE MNULNSTAT
  1513.     linedefstatus()
  1514.   ENDSELECT
  1515. ENDPROC
  1516.  
  1517. /***************************/
  1518. /**** Clear Current Map ****/
  1519. /***************************/
  1520.  
  1521. PROC newmap()
  1522.   DEF ret,r1:requester,r2:requester,active=0
  1523.  
  1524.   IF stat.woblist.head.succ<>NIL                                /* If items in list verify */
  1525.  
  1526.     ret:=butrequest('Warning','Clear current map ?','  OK  |CANCEL')
  1527.  
  1528.     IF ret                                                      /* If verified to clear    */
  1529.       IF stat.woblist.head<>NIL THEN freewobjectlist()          /* Free wobject exec list  */
  1530.       IF stat.collist.head<>NIL THEN freecolarealist()          /* Free colarea exec list  */
  1531.       cleargadgets()                                            /* Clear Wobject gadgets   */
  1532.       stat.actwobj:=NIL                                         /* Clear active gadget     */
  1533.       drawall()                                                 /* Re-Draw blank map       */
  1534.     ENDIF
  1535.   ENDIF
  1536. ENDPROC
  1537.  
  1538. /****************************/
  1539. /**** Load Line Def file ****/
  1540. /****************************/
  1541.  
  1542. PROC loadlinerequest() HANDLE
  1543.   DEF ret,active=0,r1:requester,r2:requester
  1544.   DEF pathname[PATHLEN]:STRING
  1545.  
  1546.   active:=disableinput(r1,r2)                                         /* Dissable Input   */
  1547.  
  1548.   ret:=AslRequest(linereq,[ASL_HAIL, 'Select LineDef to Load', NIL])  /* Do Requester     */
  1549.   IF ret                                                              /* If Selected file */
  1550.     StrCopy(pathname,linereq.drawer)                                  /* Concat dir/file  */
  1551.     ret:=AddPart(pathname,linereq.file,PATHLEN)
  1552.     IF ret AND pathname[0]<>0 THEN loadlinedef(pathname)              /* Call Load LineDef*/
  1553.   ENDIF
  1554. EXCEPT DO
  1555.   IF active<>0 THEN enableinput(r1,r2)                                /* Re-Enable Input  */
  1556.   ReThrow()
  1557. ENDPROC
  1558.  
  1559. /********************************/
  1560. /**** Load Specified LineDef ****/
  1561. /********************************/
  1562.  
  1563. PROC loadlinedef(pathname)
  1564.   DEF handle=NIL,n,len,fail=0
  1565.  
  1566.   handle:=Open(pathname,MODE_OLDFILE)                             /* Open LineDef file      */
  1567.   IF handle
  1568.     IF linedef<>NIL                                               /* Free existing defs     */
  1569.       Dispose(linedef)
  1570.       linedef:=NIL
  1571.     ENDIF
  1572.     IF linedef=NIL THEN linedef:=New(SIZEOF linedef)              /* Allocat new Defs       */
  1573.     IF linedef=NIL THEN RETURN                                    /* If failed return       */
  1574.     len:=Read(handle,linedef,SIZEOF linedef)                      /* Read in LineDef        */
  1575.     IF len=SIZEOF linedef
  1576.       IF linedef.magic<>LINDEFMAGIC                               /* In-correct Type        */
  1577.         butrequest('WorldED','File is not correct type',' OK ')
  1578.         fail:=1
  1579.       ENDIF
  1580.     ELSE
  1581.       butrequest('WorldED','File is truncated',' OK ')            /* File Truncated         */
  1582.       fail:=1
  1583.     ENDIF
  1584.     Close(handle)
  1585.   ELSE
  1586.     butrequest('WorldED','Could not open file',' OK ')            /* Could not open         */
  1587.   ENDIF
  1588.  
  1589.   IF fail=1                                                       /* Free linedef if failed */
  1590.     Dispose(linedef)
  1591.     linedef:=NIL
  1592.   ENDIF
  1593. ENDPROC
  1594.  
  1595. /***************************************/
  1596. /**** Show LineDef Status Requester ****/
  1597. /***************************************/
  1598.  
  1599. PROC linedefstatus()
  1600.   DEF buffer[512]:STRING,temp[80]:STRING
  1601.   DEF n,di:PTR TO defitem
  1602.  
  1603.   IF linedef=NIL
  1604.     StrCopy(buffer,'No LineDef currently loaded')
  1605.   ELSE
  1606.     StrCopy(buffer,'LineDef:')
  1607.     StrAdd(buffer,linereq.file)
  1608.     StrAdd(buffer,'\n')
  1609.     StringF(temp,'Spacing:\d\n',linedef.space)
  1610.     StrAdd(buffer,temp)
  1611.     FOR n:=0 TO OBDFCOUNT-1
  1612.       IF linedef.obdfid[n]<>0
  1613.         di:=findobjdef(linedef.obdfid[n],NIL)
  1614.         IF di<>NIL
  1615.           StringF(temp,'\n\d> \s',n,di.name)
  1616.           StrAdd(buffer,temp)
  1617.         ENDIF
  1618.       ENDIF
  1619.     ENDFOR
  1620.   ENDIF
  1621.   butrequest('WorldED LineDef Info',buffer,' OK ')
  1622. ENDPROC
  1623.  
  1624. /**************************************/
  1625. /**** Load Map From Disk Requester ****/
  1626. /**************************************/
  1627.  
  1628. PROC loadrequest() HANDLE
  1629.   DEF ret,active=0,r1:requester,r2:requester
  1630.   DEF pathname[PATHLEN]:STRING
  1631.  
  1632.   active:=disableinput(r1,r2)                                     /* Disable Input    */
  1633.   ret:=AslRequest(filereq,[ASL_HAIL, 'Select Map to Load', NIL])  /* Do Requester     */
  1634.   IF ret                                                          /* If Selected file */
  1635.     StrCopy(pathname,filereq.drawer)                              /* Concat dir/file  */
  1636.     ret:=AddPart(pathname,filereq.file,PATHLEN)
  1637.     IF ret AND pathname[0]<>0 THEN loadmap(pathname)              /* Call Load Map    */
  1638.   ENDIF
  1639. EXCEPT DO
  1640.   IF active<>0 THEN enableinput(r1,r2)                            /* Re-Enable Input  */
  1641.   ReThrow()
  1642. ENDPROC
  1643.  
  1644. /*********************************/
  1645. /**** Load Specified Map File ****/
  1646. /*********************************/
  1647.  
  1648. PROC loadmap(pathname:PTR TO CHAR) HANDLE
  1649.   DEF wob=1,col=1,err=1,handle=NIL,buf=NIL,len,len1,head:header
  1650.  
  1651.   handle:=Open(pathname,MODE_OLDFILE)                             /* Open map to load       */
  1652.   IF handle<>NIL                                                                       
  1653.     len:=Read(handle,head,SIZEOF header)                          /* Read file header       */
  1654.     IF len:=SIZEOF header
  1655.       IF head.magic=WOBJMAGIC
  1656.         IF head.wobcount>0
  1657.           len:=Mul(head.wobcount,SIZEOF wobject)                  /* Read all main Wobjects */
  1658.           buf:=New(len)
  1659.           len1:=Read(handle,buf,len)
  1660.           IF len1=len
  1661.             wob:=0                                                /* Set success flag       */
  1662.             freewobjectlist()                                     /* Free existing wobjects */
  1663.             freecolarealist()                                     /* Free existing colareas */
  1664.             wobjecttolist(buf,head.wobcount)                      /* Convert to execlist    */
  1665.           ENDIF
  1666.         ENDIF
  1667.         IF head.colcount>0
  1668.           len:=Mul(head.colcount, SIZEOF colarea)                 /* Read all main colareas */
  1669.           IF buf THEN Dispose(buf)
  1670.           buf:=New(len)
  1671.           len1:=Read(handle,buf,len)
  1672.           IF len1=len
  1673.             col:=0                                                /* Set success flag       */
  1674.             IF wob THEN freewobjectlist()                         /* Free existing wobjects */
  1675.             freecolarealist()                                     /* Free existing colareas */
  1676.             colareatolist(buf,head.colcount)                      /* Convert to execlist    */
  1677.           ENDIF
  1678.         ENDIF
  1679.         IF (wob=0) OR (col=0)
  1680.           cleargadgets()                                          /* Clear GUI Gadgets      */
  1681.           stat.actwobj:=NIL                                       /* Clear active wobject   */
  1682.           stat.actcol:=NIL                                        /* Clear active colarea   */
  1683.           drawall()                                               /* Re-draw all items      */
  1684.           err:=0
  1685.         ENDIF
  1686.       ENDIF
  1687.     ENDIF
  1688.   ENDIF
  1689.  
  1690.   IF err THEN EasyRequestArgs(mapwin,[SIZEOF easystruct,0,'Warning',
  1691.                               'Failed to load file',' OK ']:easystruct,NIL,NIL)
  1692. EXCEPT DO
  1693.   IF buf    THEN Dispose(buf)
  1694.   IF handle THEN Close(handle)
  1695.   ReThrow()
  1696. ENDPROC
  1697.  
  1698. /****************************************************/
  1699. /**** Convert Loaded Buffer to wobitem Exec List ****/
  1700. /****************************************************/
  1701.  
  1702. PROC wobjecttolist(buf:PTR TO wobject,count)
  1703.   DEF n,wi:PTR TO wobitem
  1704.  
  1705.   FOR n:=0 TO count-1                                       /* Loop through raw Wobjects */
  1706.     wi:=New(SIZEOF wobitem)                                 /* Allocate RAM for WobItem  */
  1707.     newnode(wi.node,NIL,0,0)                                /* Initialise node structure */
  1708.     Enqueue(stat.woblist,wi.node)                           /* Add wobject to exec list  */
  1709.  
  1710.     wi.wob.x        :=buf[n].x                              /* Copy Wobject to List Item */
  1711.     wi.wob.y        :=buf[n].y
  1712.     wi.wob.height   :=buf[n].height
  1713.     wi.wob.heading  :=buf[n].heading
  1714.     wi.wob.size     :=buf[n].size
  1715.     wi.wob.radius   :=buf[n].radius
  1716.     wi.wob.speed    :=buf[n].speed
  1717.     wi.wob.obid     :=buf[n].obid
  1718.     wi.wob.objdef[0]:=buf[n].objdef[0]
  1719.     wi.wob.objdef[1]:=buf[n].objdef[1]
  1720.     wi.wob.objdef[2]:=buf[n].objdef[2]
  1721.     wi.wob.objdef[3]:=buf[n].objdef[3]
  1722.   ENDFOR
  1723. ENDPROC
  1724.  
  1725. /****************************************************/
  1726. /**** Convert Loaded Buffer to colarea Exec List ****/
  1727. /****************************************************/
  1728.  
  1729. PROC colareatolist(buf:PTR TO colarea,count)
  1730.   DEF n,ci:PTR TO colitem
  1731.  
  1732.   FOR n:=0 TO count-1
  1733.     ci:=New(SIZEOF colitem)
  1734.     newnode(ci.node,NIL,0,0)
  1735.     Enqueue(stat.collist,ci.node)
  1736.  
  1737.     ci.col.x    :=buf[n].x
  1738.     ci.col.y    :=buf[n].y
  1739.     ci.col.width:=buf[n].width
  1740.     ci.col.depth:=buf[n].depth
  1741.     ci.col.floor:=buf[n].floor
  1742.     ci.col.ceil :=buf[n].ceil
  1743.     ci.col.id   :=buf[n].id
  1744.   ENDFOR
  1745. ENDPROC
  1746.  
  1747. /***************************************/
  1748. /**** Free Contents Of Wobject List ****/
  1749. /***************************************/
  1750.  
  1751. PROC freewobjectlist()
  1752.   DEF wi:PTR TO wobitem,next
  1753.  
  1754.   wi:=stat.woblist.head
  1755.   WHILE wi.node.succ<>NIL
  1756.     next:=wi.node.succ
  1757.     Remove(wi.node)
  1758.     Dispose(wi)
  1759.     wi:=next
  1760.   ENDWHILE
  1761. ENDPROC
  1762.  
  1763. /***************************************/
  1764. /**** Free Contents of ColArea List ****/
  1765. /***************************************/
  1766.  
  1767. PROC freecolarealist()
  1768.   DEF ci:PTR TO colitem,next
  1769.  
  1770.   ci:=stat.collist.head
  1771.   WHILE ci.node.succ<>NIL
  1772.     next:=ci.node.succ
  1773.     Remove(ci.node)
  1774.     Dispose(ci)
  1775.     ci:=next
  1776.   ENDWHILE
  1777. ENDPROC
  1778.  
  1779. /*******************************************/
  1780. /**** Save Map Using ASL File Requester ****/
  1781. /*******************************************/
  1782.  
  1783. PROC saverequest() HANDLE
  1784.   DEF ret,active=0,r1:requester,r2:requester
  1785.   DEF pathname[PATHLEN]:STRING
  1786.  
  1787.   active:=disableinput(r1,r2)                                       /* Disable Input     */
  1788.  
  1789.   IF (stat.woblist.head.succ=NIL) AND (stat.collist.head.succ=NIL)  /* Anything to save? */
  1790.     EasyRequestArgs(mapwin,[SIZEOF easystruct,0,'Warning',
  1791.                            'Nothing to Save',' OK ']:easystruct,NIL,NIL)
  1792.   ELSE
  1793.     ret:=AslRequest(filereq,[ASL_HAIL, 'Select Save Name', NIL])    /* Do Save Requester */
  1794.     IF ret                                                          /* If Selected file  */
  1795.       StrCopy(pathname,filereq.drawer)                              /* Concat dir/file   */
  1796.       ret:=AddPart(pathname,filereq.file,PATHLEN)
  1797.       IF ret AND pathname[0]<>0 THEN savemap(pathname)              /* Call Save Map     */
  1798.     ENDIF
  1799.   ENDIF
  1800. EXCEPT DO
  1801.   IF active<>0 THEN enableinput(r1,r2)                            /* Re-Enable Input   */
  1802.   ReThrow()
  1803. ENDPROC
  1804.  
  1805. /*************************************/
  1806. /**** Save Wobjects Into Map File ****/
  1807. /*************************************/
  1808.  
  1809. PROC savemap(pathname)
  1810.   DEF len,wobcount=0,colcount=0,wobcount1=0,colcount1=0,ret,handle=NIL
  1811.   DEF head:header,wi:PTR TO wobitem,ci:PTR TO colitem
  1812.  
  1813.   len:=FileLength(pathname)                                       /* Check if file exists   */
  1814.   IF len<>-1                                                      /* If Y confirm overwrite */
  1815.     ret:=EasyRequestArgs(mapwin,[SIZEOF easystruct,0,'Warning',
  1816.                          'File exists - Over write ?','  OK  |CANCEL']:easystruct,
  1817.                          NIL,NIL)
  1818.     IF ret=0 THEN RETURN                                          /* Exit if cancelled      */
  1819.   ENDIF
  1820.  
  1821.   wi:=stat.woblist.head                                           /* Count current wobjects */
  1822.   WHILE wi.node.succ<>NIL
  1823.     wi:=wi.node.succ
  1824.     wobcount++
  1825.   ENDWHILE
  1826.  
  1827.   ci:=stat.collist.head                                           /* Count current colareas */
  1828.   WHILE ci.node.succ<>NIL
  1829.     ci:=ci.node.succ
  1830.     colcount++
  1831.   ENDWHILE
  1832.  
  1833.   handle:=Open(pathname,MODE_NEWFILE)                             /* Open new file          */
  1834.   IF handle<>NIL
  1835.     head.magic:=WOBJMAGIC                                         /* Setup file header      */
  1836.     head.wobcount:=wobcount
  1837.     head.colcount:=colcount
  1838.     len:=Write(handle,head,SIZEOF header)                         /* Write file header      */
  1839.     IF len=SIZEOF header                                          /* If header OK continue  */
  1840.  
  1841.       len:=SIZEOF wobject
  1842.       wi :=stat.woblist.head                                      /* Get ptr to 1st Wobject */
  1843.       WHILE (wi.node.succ<>NIL) AND (len=SIZEOF wobject)          /* Process all Wobjects   */
  1844.         IF wi.wob.radius<=0                                       /* Save non Col WObjects  */
  1845.           len:=Write(handle,wi.wob,SIZEOF wobject)                /* Write Current Wobject  */
  1846.           IF len=SIZEOF wobject THEN wobcount1++                  /* Increment saved count  */
  1847.         ENDIF
  1848.         wi:=wi.node.succ                                          /* Move onto next wobject */
  1849.       ENDWHILE
  1850.  
  1851.       len:=SIZEOF wobject
  1852.       wi :=stat.woblist.head                                      /* Get ptr to 1st Wobject */
  1853.       WHILE (wi.node.succ<>NIL) AND (len=SIZEOF wobject)          /* Process all Wobjects   */
  1854.         IF wi.wob.radius>0                                        /* Save Col WObjects      */
  1855.           len:=Write(handle,wi.wob,SIZEOF wobject)                /* Write Current Wobject  */
  1856.           IF len=SIZEOF wobject THEN wobcount1++                  /* Increment saved count  */
  1857.         ENDIF
  1858.         wi:=wi.node.succ                                          /* Move onto next wobject */
  1859.       ENDWHILE
  1860.  
  1861.       len:=SIZEOF colarea
  1862.       ci :=stat.collist.head                                      /* Get ptr to 1sr ColArea */
  1863.       WHILE (ci.node.succ<>NIL) AND (len=SIZEOF colarea)          /* Process all ColAreas   */
  1864.         len:=Write(handle,ci.col,SIZEOF colarea)                  /* Write Current ColArea  */
  1865.         EXIT (len<>SIZEOF colarea)                                /* If failed halt save    */
  1866.         colcount1++                                               /* Increment saved count  */
  1867.         ci:=ci.node.succ                                          /* Move onto next colarea */
  1868.       ENDWHILE
  1869.  
  1870.       IF wobcount=wobcount1 AND colcount=colcount1 THEN ret:=0    /* If all saved set O.K.  */
  1871.     ENDIF
  1872.   ENDIF
  1873.  
  1874.   IF handle<>NIL THEN Close(handle)                               /* Close file as required */
  1875.  
  1876.   IF ret THEN EasyRequestArgs(mapwin,[SIZEOF easystruct,0,'Warning',
  1877.                               'Save Failed !!!!!',' OK ']:easystruct,NIL,NIL)
  1878. ENDPROC
  1879.  
  1880. /***************************************/
  1881. /**** Pass EasyGUI event to EasyGUI ****/
  1882. /***************************************/
  1883.  
  1884. /* EasyGUI returns a small posative action value, i am using 0 as exit
  1885.            & other small integers currently only used for menu events.
  1886.  
  1887.    NOTE info must be set to non-zero in EasyGUI call as when set to 0
  1888.         some event handlers assume that they have been called from
  1889.         another handler so they limit their updates.
  1890. */
  1891.  
  1892. PROC conevent()
  1893.    DEF ret
  1894.    ret:=guimessage(congh)
  1895.    IF (ret>=MNUSTART) AND (ret<=MNUEND) THEN menuhandler(ret)
  1896. ENDPROC ret
  1897.  
  1898. /**************************/
  1899. /**** EasyGUI handlers ****/
  1900. /**************************/
  1901.  
  1902. PROC modehdlr(info,newmode)
  1903.   stat.mode:=newmode
  1904. ENDPROC
  1905.  
  1906. /*** Handle Edit Type Change Events ***/
  1907.  
  1908. PROC typehdlr(info,newmode)
  1909.   disablegadgets(newmode)
  1910. ENDPROC
  1911.  
  1912. /*** Handle Zoom Integer Gadget Entry Events ***/
  1913.  
  1914. PROC zinthdlr(info,newzoom)
  1915.    DEF zoom=0
  1916.    IF newzoom > MAXZOOM THEN zoom:=MAXZOOM      /* Check against bounds */
  1917.    IF newzoom < MINZOOM THEN zoom:=MINZOOM
  1918.    IF zoom <> 0                                 /* If exceeds bounds reset to bound */
  1919.       newzoom:=zoom
  1920.       setinteger(congh,stat.zint,newzoom)
  1921.    ENDIF
  1922.    IF stat.zoom <> newzoom                      /* If zoom changed do related updates */
  1923.       stat.zoom:=newzoom
  1924.       setslide(congh,stat.zsld,newzoom)
  1925.       mxinthdlr(0,stat.x)                       /* Use co-ord gad handlers to check bounds */
  1926.       myinthdlr(0,stat.y)
  1927.       setscrollers()
  1928.    ENDIF
  1929. ENDPROC
  1930.  
  1931. /*** Handle Zoom Slider Events ***/
  1932.  
  1933. PROC zslidehdlr(info,newzoom)
  1934.    IF stat.zoom <> newzoom                      /* If zoom changed do related updates */
  1935.       stat.zoom:=newzoom
  1936.       setinteger(congh,stat.zint,newzoom)
  1937.       mxinthdlr(0,stat.x)                       /* Use co-ord gad handlers to check bounds */
  1938.       myinthdlr(0,stat.y)
  1939.       setscrollers()
  1940.    ENDIF
  1941. ENDPROC
  1942.  
  1943. /*** Handle Map X-Coord Gadget Events ***/
  1944.  
  1945. PROC mxinthdlr(info,newx)                       /*** if info=0 don't initiate redraw ***/
  1946.    DEF x=-1,max
  1947.    max:=MAXCOORD-Div(MAXCOORD,stat.zoom)        /* Calculate current maximum X-Coord */
  1948.    IF max > 0 THEN max--
  1949.    IF newx > max THEN x:=max                    /* Check X Co-ord against bounds */
  1950.    IF newx < 0   THEN x:=0
  1951.    IF x <> -1 THEN newx:=x                      /* If exceeds bounds reset to bound */
  1952.    IF (stat.x <> newx) OR (x <> -1)             /* If X Coord changed do related updates */
  1953.       stat.x:=newx
  1954.       setinteger(congh,stat.mxint,newx)
  1955.       IF info <> 0 THEN setscrollers()
  1956.    ENDIF
  1957. ENDPROC
  1958.  
  1959. /*** Handle Map Y-Coord Gadget Events ***/
  1960.  
  1961. PROC myinthdlr(info,newy)                       /*** if info=0 don't initiate redraw ***/
  1962.    DEF y=-1,max
  1963.    max:=MAXCOORD-Div(MAXCOORD,stat.zoom)        /* Calculate current maximum Y-Coord */
  1964.    IF max > 0 THEN max--
  1965.    IF newy > max THEN y:=max                    /* Check Y Co-ord against bounds */
  1966.    IF newy < 0   THEN y:=0
  1967.    IF y <> -1 THEN newy:=y                      /* If exceeded bounds change new y */
  1968.    IF (stat.y <> newy) OR (y <> -1)             /* If Y Coord changed do related updates */
  1969.       stat.y:=newy
  1970.       setinteger(congh,stat.myint,newy)
  1971.       IF info <> 0 THEN setscrollers()
  1972.    ENDIF
  1973. ENDPROC
  1974.  
  1975. /*** Width,Depth,Floor,Ceiling Gadget Event Handler ***/
  1976.  
  1977. PROC widinthdlr(info,new)
  1978.   stat.wid:=Bounds(new,MINWID,MAXWID)
  1979.   setinteger(congh,stat.widint,stat.wid)
  1980. ENDPROC
  1981.  
  1982. PROC depinthdlr(info,new)
  1983.   stat.dep:=Bounds(new,MINDEP,MAXDEP)
  1984.   setinteger(congh,stat.depint,stat.dep)
  1985. ENDPROC
  1986.  
  1987. PROC flrinthdlr(info,new)
  1988.   stat.flr:=Bounds(new,MINFLR,MAXFLR)
  1989.   IF stat.flr > stat.ceil THEN stat.flr:=stat.ceil
  1990.   setinteger(congh,stat.flrint,stat.flr)
  1991. ENDPROC
  1992.  
  1993. PROC ceilinthdlr(info,new)
  1994.   stat.ceil:=Bounds(new,MINCEIL,MAXCEIL)
  1995.   IF stat.ceil < stat.flr THEN stat.ceil:=stat.flr
  1996.   setinteger(congh,stat.ceilint,stat.ceil)
  1997. ENDPROC
  1998.  
  1999. /*** Altitude,Heading,Size,Radius & Type/ID Gadget Event Handlers ***/
  2000.  
  2001. PROC altinthdlr(info,new)
  2002.   stat.alt:=Bounds(new,MINALT,MAXALT)
  2003.   setinteger(congh,stat.altint,stat.alt)
  2004. ENDPROC
  2005.  
  2006. PROC headinthdlr(info,new)
  2007.   stat.head:=Bounds(new,MINHEAD,MAXHEAD)
  2008.   setinteger(congh,stat.headint,stat.head)
  2009. ENDPROC
  2010.  
  2011. PROC sizeinthdlr(info,new)
  2012.   stat.size:=Bounds(new,MINSIZE,MAXSIZE)
  2013.   setinteger(congh,stat.sizeint,stat.size)
  2014. ENDPROC
  2015.  
  2016. PROC cradinthdlr(info,new)
  2017.   stat.crad:=Bounds(new,MINCRAD,MAXCRAD)
  2018.   setinteger(congh,stat.cradint,stat.crad)
  2019. ENDPROC
  2020.  
  2021. PROC obidinthdlr(info,new)
  2022.   stat.obid:=Bounds(new,MINOBID,MAXOBID)
  2023.   setinteger(congh,stat.obidint,stat.obid)
  2024. ENDPROC
  2025.  
  2026. PROC passchkhdlr(info,checked)
  2027.   stat.pass:=checked
  2028. ENDPROC
  2029.  
  2030. /*** Handle Object World X-Coord Events ***/
  2031.  
  2032. PROC wxinthdlr(info,newx)
  2033.   stat.wx:=Bounds(newx,0,MAXCOORD-1)
  2034.   setinteger(congh,stat.wxint,stat.wx)
  2035. ENDPROC
  2036.  
  2037. /*** Handle Object World Y-Coors Events ***/
  2038.  
  2039. PROC wyinthdlr(info,newy)
  2040.   stat.wy:=Bounds(newy,0,MAXCOORD-1)
  2041.   setinteger(congh,stat.wyint,stat.wy)
  2042. ENDPROC
  2043.  
  2044. /*** Handle Object Definition 0 Gadgets ***/
  2045.  
  2046. PROC obdfstrhdlr0() IS setstr(congh,stat.obdfstr[0],os0)
  2047. PROC obdfbuthdlr0() IS selectobjdef(0)
  2048.  
  2049. /*** Handle Object Definition 1 Gadgets ***/
  2050.  
  2051. PROC obdfstrhdlr1() IS setstr(congh,stat.obdfstr[1],os1)
  2052. PROC obdfbuthdlr1() IS selectobjdef(1)
  2053.  
  2054. /*** Handle Object Definition 2 Gadgets ***/
  2055.  
  2056. PROC obdfstrhdlr2() IS setstr(congh,stat.obdfstr[2],os2)
  2057. PROC obdfbuthdlr2() IS selectobjdef(2)
  2058.  
  2059. /*** Handle Object Definition 3 Gadgets ***/
  2060.  
  2061. PROC obdfstrhdlr3() IS setstr(congh,stat.obdfstr[3],os3)
  2062. PROC obdfbuthdlr3() IS selectobjdef(3)
  2063.  
  2064. /*** Handle Update GUI to Active WObject Button ***/
  2065.  
  2066. PROC updbuthdlr()
  2067.   IF stat.edtype
  2068.     IF stat.actcol<>NIL
  2069.       coldraw(stat.actcol,1,0)                                    /* Un-draw current active */
  2070.       gui2col(stat.actcol)                                        /* Update & Re-draw it    */
  2071.     ELSE
  2072.       butrequest('Warning','No Col Box Selected\nCant Update !!!!',' OK ')
  2073.     ENDIF
  2074.   ELSE
  2075.     IF stat.obdfid[0]=NIL                                         /* Check ObjDef Settings  */
  2076.       butrequest('Warning','No Primary ObjDef Specified',' OK ')
  2077.       RETURN
  2078.     ENDIF
  2079.     IF stat.actwobj<>NIL
  2080.       wobjdraw(stat.actwobj,1,0)                                  /* Un-draw current active */
  2081.       gui2wobj(stat.actwobj)                                      /* Update & Re-draw it    */
  2082.     ELSE
  2083.       butrequest('Warning','No Object Selected\nCant Update !!!!',' OK ')
  2084.     ENDIF
  2085.   ENDIF
  2086. ENDPROC
  2087.  
  2088. /*** Handle Clear Current Active WObject Button ***/
  2089.  
  2090. /* If info is 0 the not called from GUI so requester no displayed */
  2091.  
  2092. PROC clrbuthdlr(info)
  2093.   DEF ret
  2094.   IF info
  2095.     ret:=butrequest('W.E. Request','Clear Gadgets ?','  OK  |CANCEL')
  2096.     IF ret=0 THEN RETURN
  2097.   ENDIF
  2098.   IF stat.edtype
  2099.     IF stat.actcol<>NIL
  2100.       setactcol(NIL)                                     /* Set Active to NIL (Un-draw old) */
  2101.       stat.actcol:=NIL                                   /* Clear active object pointers    */
  2102.     ENDIF
  2103.   ELSE
  2104.     IF stat.actwobj<>NIL
  2105.       setactwobj(NIL)                                    /* Set Active to NIL (Un-draw old) */
  2106.       stat.actwobj:=NIL                                  /* Clear active object pointers    */
  2107.     ENDIF
  2108.   ENDIF                                                                             
  2109.   cleargadgets()
  2110. ENDPROC
  2111.  
  2112. /***************************************************/
  2113. /*** Dissable Gadgets Based on Type Being Edited ***/
  2114. /***************************************************/
  2115.  
  2116. PROC disablegadgets(edtype)
  2117.   DEF gadg,n
  2118.  
  2119.   stat.edtype:=edtype
  2120.   gadg:=findgadget(congh,stat.widint)
  2121.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype-1, NIL])
  2122.   gadg:=findgadget(congh,stat.depint)
  2123.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype-1, NIL])
  2124.   gadg:=findgadget(congh,stat.flrint)
  2125.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype-1, NIL])
  2126.   gadg:=findgadget(congh,stat.ceilint)
  2127.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype-1, NIL])
  2128.  
  2129.   gadg:=findgadget(congh,stat.altint)
  2130.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2131.   gadg:=findgadget(congh,stat.headint)
  2132.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2133.   gadg:=findgadget(congh,stat.sizeint)
  2134.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2135.   gadg:=findgadget(congh,stat.cradint)
  2136.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2137.   gadg:=findgadget(congh,stat.passchk)
  2138.   Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2139.  
  2140.   FOR n:=0 TO 3
  2141.     gadg:=findgadget(congh,stat.obdfstr[n])
  2142.     Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2143.     gadg:=findgadget(congh,stat.obdfbut[n])
  2144.     Gt_SetGadgetAttrsA(gadg, congh.wnd, NIL, [GA_DISABLED, edtype, NIL])
  2145.   ENDFOR
  2146. ENDPROC
  2147.  
  2148. /********************************************/
  2149. /**** Clear Gadgets in GUI & Stat copies ****/
  2150. /********************************************/
  2151.  
  2152. PROC cleargadgets()
  2153.   stat.wx  :=0                                    /* Clear Interface Buffers & Gadgets */
  2154.   stat.wy  :=0
  2155.  
  2156.   IF stat.edtype
  2157.     stat.wid :=0
  2158.     stat.dep :=0
  2159.     stat.flr :=0
  2160.     stat.ceil:=0
  2161.   ELSE
  2162.     stat.alt :=0
  2163.     stat.head:=0
  2164.     stat.size:=512
  2165.     stat.crad:=0
  2166.     stat.obid:=0
  2167.     stat.pass:=FALSE
  2168.     stat.obdfid[0]:=0
  2169.     stat.obdfid[1]:=0
  2170.     stat.obdfid[2]:=0
  2171.     stat.obdfid[3]:=0
  2172.   ENDIF
  2173.   stat2gui()
  2174. ENDPROC
  2175.  
  2176. PROC stat2gui()
  2177.   setinteger(congh,stat.wxint,stat.wx)
  2178.   setinteger(congh,stat.wyint,stat.wy)
  2179.  
  2180.   IF stat.edtype
  2181.     setinteger(congh,stat.widint,stat.wid)
  2182.     setinteger(congh,stat.depint,stat.dep)
  2183.     setinteger(congh,stat.flrint,stat.flr)
  2184.     setinteger(congh,stat.ceilint,stat.ceil)
  2185.   ELSE
  2186.     setinteger(congh,stat.altint,stat.alt)
  2187.     setinteger(congh,stat.headint,stat.head)
  2188.     setinteger(congh,stat.sizeint,stat.size)
  2189.     setinteger(congh,stat.cradint,stat.crad)
  2190.     setinteger(congh,stat.obidint,stat.obid)
  2191.     setcheck(congh,stat.passchk,stat.pass)
  2192.     StrCopy(os0,'')
  2193.     setstr(congh,stat.obdfstr[0],os0)
  2194.     StrCopy(os1,'')
  2195.     setstr(congh,stat.obdfstr[1],os1)
  2196.     StrCopy(os2,'')
  2197.     setstr(congh,stat.obdfstr[2],os2)
  2198.     StrCopy(os3,'')
  2199.     setstr(congh,stat.obdfstr[3],os3)
  2200.   ENDIF
  2201. ENDPROC
  2202.  
  2203. /*************************************************************/
  2204. /*** Set Map Window Scroller Gadgets to Current GUI status ***/
  2205. /*************************************************************/
  2206.  
  2207. PROC setscrollers()
  2208. DEF xpot,ypot,bod,rng,x,y
  2209.  
  2210.    bod :=Div(MAXBODY+1,stat.zoom)-1                         /* Calculate Body Value */
  2211.  
  2212.    rng :=Shr(MAXCOORD,7)                                    /* Calculate co-ord range */
  2213.    rng :=rng-Div(rng,stat.zoom)                             /* Scaled down by >>7     */
  2214.    IF rng = 0 THEN rng:=1
  2215.  
  2216.    x:=Shl(stat.x,2)+1                                       /* Scale down co-ords >>7 and */
  2217.    y:=Shl(stat.y,2)+1                                       /* increase precision <<9     */
  2218.  
  2219.    xpot:=Div(x,rng)                                         /* Calc pot as fraction of 1024 */
  2220.    IF xpot = 0 THEN xpot:=1                                 /* Check against minimum        */
  2221.    xpot:=Shr(Mul((MAXBODY+1),xpot),9)-1                     /* Multiply pot val by fraction */
  2222.  
  2223.    ypot:=Div(y,rng)                                         /* Calc pot as fraction of 1024 */
  2224.    IF ypot = 0 THEN ypot:=1                                 /* Check against minimum        */
  2225.    ypot:=Shr(Mul((MAXBODY+1),ypot),9)-1                     /* Multiply pot val by fraction */
  2226.  
  2227.    NewModifyProp(hscrl,mapwin,NIL,hinfo.flags,xpot,0,bod,MAXBODY,1) /* Update Vert Scroller */
  2228.    NewModifyProp(vscrl,mapwin,NIL,vinfo.flags,0,ypot,MAXBODY,bod,1) /* Update Horz Scroller */
  2229.  
  2230.    drawall()                                                        /* Re-draw map window */
  2231. ENDPROC
  2232.  
  2233. /************************************************/
  2234. /*** Get Scroller Gadger Setting & Update GUI ***/
  2235. /************************************************/
  2236.  
  2237. PROC getvscroller()                                /*** Update Y Co-ord Gadget  ***/
  2238.    DEF rng,newp,newy
  2239.    newp:=Shr(UNSIGNED(vinfo.vertpot),6)            /* Get Current Pot Position    */
  2240.    rng :=MAXCOORD-Div(MAXCOORD,stat.zoom)+50       /* Calc Current Y Co-ord range */
  2241.    IF rng=0 THEN rng:=1
  2242.    newy:=Shr(Mul(rng,newp),10)                     /* Calc Current (new) Y Co-ord */
  2243.    IF newy<>stat.y                                 /* If y Position Changed do :- */
  2244.      myinthdlr(0,newy)                             /* Update Y Integer Gadget     */
  2245.      drawall()                                     /* Re-draw Map Window          */
  2246.    ENDIF
  2247. ENDPROC
  2248.  
  2249. PROC gethscroller()                                /*** Update X Co-ord Gadget  ***/
  2250.    DEF rng,newp,newx
  2251.    newp:=Shr(UNSIGNED(hinfo.horizpot),6)           /* Get Current Pot Position    */
  2252.    rng :=MAXCOORD-Div(MAXCOORD,stat.zoom)+50       /* Calc Current X Co-ord range */
  2253.    IF rng=0 THEN rng:=1
  2254.    newx:=Shr(Mul(rng,newp),10)                     /* Calc Current (new) Y Co-ord */
  2255.    IF newx<>stat.x                                 /* If x Position Changed do :- */
  2256.      mxinthdlr(0,newx)                             /* Update Y Integer Gadget     */
  2257.      drawall()                                     /* Re-draw Map Window          */
  2258.    ENDIF
  2259. ENDPROC
  2260.  
  2261. /**********************************************************/
  2262. /*** Block & Un-Block Messages to Map & Control Windows ***/
  2263. /**********************************************************/
  2264.  
  2265. /* Parameters - Pointers to two un-init'd requester structures
  2266.  
  2267.    disableinput returns 1 for setting active flag
  2268.    enableinput  returns 0 for clearing active flag
  2269. */
  2270.  
  2271. PROC disableinput(req1,req2)
  2272.   InitRequester(req1)                 /* Initialise Requester Structures */
  2273.   InitRequester(req2)
  2274.   Request(req1,congh.wnd)             /* Block Input to Windows */
  2275.   Request(req2,mapwin)
  2276. ENDPROC 1
  2277.  
  2278. PROC enableinput(req1,req2)
  2279.   EndRequest(req2,mapwin)             /* Enable Input to Windows */
  2280.   EndRequest(req1,congh.wnd)
  2281. ENDPROC 0
  2282.  
  2283. /*************************************************/
  2284. /*** Pick ObjDef from list to apply to WObject ***/
  2285. /*************************************************/
  2286.  
  2287. /* Defnum = definition slot on WObject to be set */
  2288.  
  2289. PROC selectobjdef(defnum) HANDLE
  2290.   DEF active=0,ret=-1,req1:requester,req2:requester
  2291.   DEF defstr[16]:STRING,gh=NIL:PTR TO guihandle
  2292.   DEF work:guiwork
  2293.  
  2294.   work.str:=defstr                                /* Record E-String pointer */
  2295.  
  2296.   active:=disableinput(req1,req2)                 /* Disable Window Input */
  2297.  
  2298.   gh:=guiinit('Select Definition',                /* Build EasyGUI Interface */
  2299.               [ROWS,            
  2300.                 [LISTV,{getdefsel},'Definitions',15,6,stat.deflist,1,0,0],
  2301.                 [COLS,
  2302.                   [BUTTON,1,'  OK  '],
  2303.                   [BUTTON,2,'CLEAR'],
  2304.                   [BUTTON,0,'CANCEL']
  2305.                 ]
  2306.               ],work,scrn)
  2307.  
  2308.   WHILE ret<0                                     /* Loop Until OK or Cancel Hit */
  2309.     Wait(gh.sig)                                  /* Wait for IDCMP message      */
  2310.     ret:=guimessage(gh)                           /* Pass message to EasyGUI     */
  2311.     IF defstr[0]<>0 THEN ret:=3                   /* If Str Select String Hit    */
  2312.   ENDWHILE
  2313.  
  2314.   IF gh THEN cleangui(gh)                         /* If open close down GUI */
  2315.   IF active THEN active:=enableinput(req1,req2)   /* Re-Enable Window Input */
  2316.  
  2317.   IF ret=2
  2318.     StrCopy(defstr,'')                            /* If Clear hit - Clear String */
  2319.     work.val:=0                                   /* Clear ID number of ObjDef   */
  2320.   ENDIF
  2321.   IF ret>1                                        /* If Item Selected or Cleared */
  2322.     stat.obdfid[defnum]:=work.val                 /* Store Selected objdef's ID  */
  2323.     SELECT defnum                                 /* Set required String Gadget  */
  2324.     CASE 0
  2325.       StrCopy(os0,defstr)
  2326.       setstr(congh,stat.obdfstr[0],os0)
  2327.     CASE 1
  2328.       StrCopy(os1,defstr)
  2329.       setstr(congh,stat.obdfstr[1],os1)
  2330.     CASE 2
  2331.       StrCopy(os2,defstr)
  2332.       setstr(congh,stat.obdfstr[2],os2)
  2333.     CASE 3
  2334.       StrCopy(os3,defstr)
  2335.       setstr(congh,stat.obdfstr[3],os3)
  2336.     ENDSELECT
  2337.   ENDIF
  2338. EXCEPT
  2339.   IF gh THEN cleangui(gh)                         /* If open close down GUI */
  2340.   IF active THEN enableinput(req1,req2)           /* Re-Enable Window Input */
  2341.   IF exception > 0 THEN Raise(exception)          /* On except call base exception handler */
  2342.   ReThrow()
  2343. ENDPROC
  2344.  
  2345. /*** Record Selected Definition name in Info E-String ***/
  2346.  
  2347. PROC getdefsel(info:PTR TO guiwork,selnum)
  2348.   DEF node:PTR TO ln,count=0
  2349.   DEF item:PTR TO defitem
  2350.  
  2351.   node:=stat.deflist.head                         /* Get pointer to 1st node  */
  2352.   WHILE (node.succ<>NIL) AND (count<selnum)       /* Loop until selected item */
  2353.     node:=node.succ                               /* Move to next node        */
  2354.     count++                                       /* Increment node counter   */
  2355.   ENDWHILE
  2356.   item:=node                                      /* Convert to defitem ptr   */
  2357.   StrCopy(info.str,node.name)                     /* Store name from node     */
  2358.   info.val:=item.id                               /* Store ID from node       */
  2359. ENDPROC
  2360.  
  2361. /*********************************/
  2362. /*** Display Warning Requester ***/
  2363. /*********************************/
  2364.  
  2365. PROC butrequest(title:PTR TO CHAR,text:PTR TO CHAR,gad:PTR TO CHAR) HANDLE
  2366.   DEF active=0,ret,req1:requester,req2:requester
  2367.  
  2368.   active:=disableinput(req1,req2)
  2369.  
  2370.   ret:=EasyRequestArgs(mapwin,
  2371.                       [SIZEOF easystruct,0,title,text,gad]:easystruct,
  2372.                       NIL,NIL)
  2373. EXCEPT DO
  2374.   IF active THEN enableinput(req1,req2)
  2375.   ReThrow()
  2376. ENDPROC ret
  2377.  
  2378. /***************************************************/
  2379. /*** Transfer Data Between WObject/ColArea & GUI ***/
  2380. /***************************************************/
  2381.  
  2382. PROC gui2wobj(wobj:PTR TO wobject)
  2383.   wobj.x      :=stat.wx
  2384.   wobj.y      :=stat.wy
  2385.   wobj.height :=stat.alt
  2386.   wobj.heading:=stat.head
  2387.   wobj.size   :=stat.size
  2388.   wobj.radius :=stat.crad
  2389.   IF stat.pass THEN wobj.radius:=0-wobj.radius
  2390.   wobj.obid   :=stat.obid
  2391.   wobj.objdef[0]:=stat.obdfid[0]
  2392.   wobj.objdef[1]:=stat.obdfid[1]
  2393.   wobj.objdef[2]:=stat.obdfid[2]
  2394.   wobj.objdef[3]:=stat.obdfid[3]
  2395.   setactwobj(wobj)
  2396. ENDPROC
  2397.  
  2398. PROC gui2col(col:PTR TO colarea)
  2399.   col.x    :=stat.wx
  2400.   col.y    :=stat.wy
  2401.   col.width:=stat.wid
  2402.   col.depth:=stat.dep
  2403.   col.floor:=stat.flr
  2404.   col.ceil :=stat.ceil
  2405.   col.id   :=stat.obid
  2406.   setactcol(col)
  2407. ENDPROC
  2408.  
  2409. PROC wobj2gui(wobj:PTR TO wobject)
  2410.   DEF n, di:PTR TO defitem
  2411.  
  2412.   stat.wx  :=wobj.x
  2413.   stat.wy  :=wobj.y
  2414.   stat.alt :=wobj.height
  2415.   stat.head:=wobj.heading
  2416.   stat.size:=wobj.size
  2417.   stat.crad:=wobj.radius
  2418.   stat.obid:=wobj.obid
  2419.   stat.pass:=FALSE
  2420.  
  2421.   IF wobj.radius<=0
  2422.     stat.pass:=TRUE
  2423.     stat.crad:=0-stat.crad
  2424.   ENDIF
  2425.  
  2426.   stat.obdfid[0]:=wobj.objdef[0]
  2427.   stat.obdfid[1]:=wobj.objdef[1]
  2428.   stat.obdfid[2]:=wobj.objdef[2]
  2429.   stat.obdfid[3]:=wobj.objdef[3]
  2430.  
  2431.   setinteger(congh,stat.wxint,stat.wx)
  2432.   setinteger(congh,stat.wyint,stat.wy)
  2433.   setinteger(congh,stat.altint,stat.alt)
  2434.   setinteger(congh,stat.headint,stat.head)
  2435.   setinteger(congh,stat.sizeint,stat.size)
  2436.   setinteger(congh,stat.cradint,stat.crad)
  2437.   setinteger(congh,stat.obidint,stat.obid)
  2438.   setcheck(congh,stat.passchk,stat.pass)
  2439.  
  2440.   IF stat.obdfid[0]<>0 THEN di:=findobjdef(stat.obdfid[0],NIL) ELSE di:=NIL
  2441.   IF di<>NIL THEN StrCopy(os0,di.name) ELSE StrCopy(os0,'')
  2442.   setstr(congh,stat.obdfstr[0],os0)
  2443.  
  2444.   IF stat.obdfid[1]<>0 THEN di:=findobjdef(stat.obdfid[1],NIL) ELSE di:=NIL
  2445.   IF di<>NIL THEN StrCopy(os1,di.name) ELSE StrCopy(os1,'')
  2446.   setstr(congh,stat.obdfstr[1],os1)
  2447.  
  2448.   IF stat.obdfid[2]<>0 THEN di:=findobjdef(stat.obdfid[2],NIL) ELSE di:=NIL
  2449.   IF di<>NIL THEN StrCopy(os2,di.name) ELSE StrCopy(os2,'')
  2450.   setstr(congh,stat.obdfstr[2],os2)
  2451.  
  2452.   IF stat.obdfid[3]<>0 THEN di:=findobjdef(stat.obdfid[3],NIL) ELSE di:=NIL
  2453.   IF di<>NIL THEN StrCopy(os3,di.name) ELSE StrCopy(os3,'')
  2454.   setstr(congh,stat.obdfstr[3],os3)
  2455.  
  2456.   setactwobj(wobj)
  2457. ENDPROC
  2458.  
  2459. PROC col2gui(col:PTR TO colarea)
  2460.   stat.wx  :=col.x
  2461.   stat.wy  :=col.y
  2462.   stat.wid :=col.width
  2463.   stat.dep :=col.depth
  2464.   stat.flr :=col.floor
  2465.   stat.ceil:=col.ceil
  2466.   stat.obid:=col.id
  2467.  
  2468.   setinteger(congh,stat.wxint,stat.wx)
  2469.   setinteger(congh,stat.wyint,stat.wy)
  2470.   setinteger(congh,stat.widint,stat.wid)
  2471.   setinteger(congh,stat.depint,stat.dep)
  2472.   setinteger(congh,stat.flrint,stat.flr)
  2473.   setinteger(congh,stat.ceilint,stat.ceil)
  2474.   setinteger(congh,stat.obidint,stat.obid)
  2475.  
  2476.   setactcol(col)
  2477. ENDPROC
  2478.  
  2479. /******************************************/
  2480. /*** Set Current Active WObject/ColArea ***/
  2481. /******************************************/
  2482.  
  2483. /* Pointer to WObject to make active or NIL if clearing active */
  2484.  
  2485. PROC setactwobj(newwobj:PTR TO wobject)
  2486.   DEF oldwobj:PTR TO wobject
  2487.   oldwobj:=stat.actwobj                     /* Get previous active wobject */
  2488.   stat.actwobj:=newwobj                     /* Set new active wobject      */
  2489.   SetStdRast(mapwin.rport)                  /* Setup for Mapwin drawing    */
  2490.   IF oldwobj<>NIL THEN wobjdraw(oldwobj,0,0)  /* Redraw affect wobjects      */
  2491.   IF newwobj<>NIL THEN wobjdraw(newwobj,0,0)
  2492. ENDPROC
  2493.  
  2494. /* Pointer to ColArea to make active of NIL if clearing active */ 
  2495.  
  2496. PROC setactcol(newcol:PTR TO colarea)
  2497.   DEF oldcol:PTR TO colarea
  2498.   oldcol:=stat.actcol
  2499.   stat.actcol:=newcol
  2500.   SetStdRast(mapwin.rport)
  2501.   IF oldcol<>NIL THEN coldraw(oldcol,0,0)
  2502.   IF newcol<>NIL THEN coldraw(newcol,0,0)
  2503. ENDPROC
  2504.  
  2505. /***********************************************/
  2506. /*** Find Object Definition using Name or ID ***/
  2507. /***********************************************/
  2508.  
  2509. /* If fill in one of params and leave other as NIL
  2510.    Returns pointer to defitem or NIL
  2511. */
  2512.  
  2513. PROC findobjdef(id,str)
  2514.   DEF di:PTR TO defitem,ret=NIL
  2515.   di:=stat.deflist
  2516.   WHILE di.node.succ<>NIL
  2517.     IF (id<>0) AND (id=di.id) THEN ret:=di
  2518.     IF (str[0]<>0) AND StrCmp(str,di.name) THEN ret:=di
  2519.     di:=di.node.succ
  2520.   ENDWHILE
  2521. ENDPROC ret
  2522.  
  2523. /******************************************/
  2524. /*** Find Wobject Base on World Co-ords ***/
  2525. /******************************************/
  2526.  
  2527. /* Parameters - world x,y co-ords
  2528.    Returns    - Pointer to 1st wobject found to be under these co-ords
  2529.                 otherwise NIL returned.
  2530. */
  2531.  
  2532. PROC findwobjcoord(x,y)
  2533.   DEF x1,x2,y1,y2,sz,wi:PTR TO wobitem
  2534.  
  2535.   wi:=stat.woblist.head                                                /* Find First Item   */
  2536.   WHILE wi.node.succ<>NIL                                              /* If not blank      */
  2537.     sz:=wi.wob.radius                                                  /* Get size of item  */
  2538.     IF sz<0 THEN sz:=0-sz                                              /* If negative flip+ */
  2539.     IF sz<4 THEN sz:=4                                                 /* Bound to minimum  */
  2540.     x1:=wi.wob.x-sz                                                    /* Calculate hot box */
  2541.     x2:=wi.wob.x+sz
  2542.     y1:=wi.wob.y-sz
  2543.     y2:=wi.wob.y+sz
  2544.     IF (x>=x1) AND (x<=x2) AND (y>=y1) AND (y<=y2) THEN RETURN wi.wob  /* return wob if hit */
  2545.     wi:=wi.node.succ                                                   /* Get next item     */
  2546.   ENDWHILE
  2547. ENDPROC NIL
  2548.  
  2549. /*******************************************/
  2550. /*** Find ColArea Based on World Co-ords ***/
  2551. /*******************************************/
  2552.  
  2553. /* Parameters - world x,y co-ords
  2554.    Returns    - Pointer to 1st colarea found to be under these co-ords
  2555.                 otherwise NIL returned.
  2556. */
  2557.  
  2558. PROC findcolcoord(x,y)
  2559.   DEF x1,y1,x2,y2,col:PTR TO colitem
  2560.  
  2561.   col:=stat.collist.head                                               /* Find First Item   */
  2562.   WHILE col.node.succ<>NIL                                             /* If not  blank     */
  2563.     x1:=col.col.x                                                      /* Get co-ords       */
  2564.     y1:=col.col.y
  2565.     x2:=x1+col.col.width
  2566.     y2:=y1+col.col.depth
  2567.     IF (x>=x1) AND (x<=x2) AND (y>=y1) AND (y<=y2) THEN RETURN col.col /* return col if hit */
  2568.     col:=col.node.succ                                                 /* get next item     */
  2569.   ENDWHILE
  2570. ENDPROC NIL
  2571.  
  2572. /*************************************/
  2573. /*** Draw in wobject(s)/colarea(s) ***/
  2574. /*************************************/
  2575.  
  2576. /* NOTE - Shifts are to maintain precision */
  2577.  
  2578. PROC drawall()
  2579.   DEF pixdiv
  2580.   DEF wob:PTR TO wobitem
  2581.   DEF col:PTR TO colitem
  2582.   SetStdRast(mapwin.rport)                            /* Setup for Mapwin drawing   */
  2583.   Box(0,0,MAPWINSIZE,MAPWINSIZE,0)                    /* Clear Map Window           */
  2584.  
  2585.   pixdiv:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE)
  2586.  
  2587.   griddraw(pixdiv)                                    /* Draw in Grid               */
  2588.  
  2589.   wob:=stat.woblist.head                              /* Get Start of wobitem List  */
  2590.   WHILE wob.node.succ<>NIL                            /* If Valid wobitem           */
  2591.     wobjdraw(wob.wob,0,pixdiv)                        /* Draw it in Map Window      */
  2592.     wob.select:=0                                     /* Clear group selection info */
  2593.     wob:=wob.node.succ                                /* Get Next wobitem           */
  2594.   ENDWHILE
  2595.  
  2596.   col:=stat.collist.head                              /* Get Start of colitem list  */
  2597.   WHILE col.node.succ<>NIL                            /* If Valid colitem           */
  2598.     coldraw(col.col,0,pixdiv)                         /* Draw it in mapwindow       */
  2599.     col.select:=0                                     /* Clear group selection info */
  2600.     col:=col.node.succ                                /* Get Next colitem           */
  2601.   ENDWHILE
  2602. ENDPROC
  2603.  
  2604.  
  2605. PROC griddraw(pixdiv)
  2606.   DEF sx,sy,scrx,scry
  2607.  
  2608.   sx:=Shl(Shr(stat.x,8)+1,8)
  2609.   sy:=Shl(Shr(stat.y,8)+1,8)
  2610.  
  2611.   scrx:=Div(Shl((sx - stat.x),9),pixdiv)
  2612.   WHILE scrx < MAPWINSIZE
  2613.     Line(scrx,0,scrx,MAPWINSIZE-1,GREEN)
  2614.     sx:=sx+256
  2615.     scrx:=Div(Shl((sx - stat.x),9),pixdiv)
  2616.   ENDWHILE
  2617.  
  2618.   scry:=Div(Shl((sy - stat.y),9),pixdiv)
  2619.   WHILE scry < MAPWINSIZE
  2620.     Line(0,scry,MAPWINSIZE-1,scry,GREEN)
  2621.     sy:=sy+256
  2622.     scry:=Div(Shl((sy - stat.y),9),pixdiv)
  2623.   ENDWHILE
  2624.  
  2625. ENDPROC
  2626.  
  2627.  
  2628. /* If colovr is non zero then colour is over ridden to col-1
  2629.    otherwise is based on attributes of wobject/colarea
  2630.  
  2631.    If pixdiv is set this value is used instead of calculating
  2632.    it again. Speeds up drawall().
  2633. */
  2634.  
  2635. PROC wobjdraw(wobj:PTR TO wobject,colovr,pixdiv)
  2636.   DEF x,y,t,s,x1,y1,x2,y2,col,sz
  2637.  
  2638.   IF wobj.radius<=0                                   /* Base map size & Color on radius */
  2639.     col:=WHITE
  2640.     sz:=0-wobj.radius
  2641.   ELSE
  2642.     col:=BLACK
  2643.     sz:=wobj.radius
  2644.   ENDIF
  2645.   IF sz<4 THEN sz:=4
  2646.  
  2647.   IF wobj=stat.actwobj THEN col:=RED                  /* If Active Object Draw Red */
  2648.   IF colovr>0 THEN col:=colovr-1
  2649.  
  2650.   IF pixdiv<>0
  2651.     t:=pixdiv                                         /* Use passed Pixel Divisor  */
  2652.   ELSE
  2653.     t:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE) /* Calculate Pixel Divisor   */
  2654.   ENDIF
  2655.  
  2656.   x:=Div(Shl((wobj.x - stat.x),9),t)                  /* Calc Window X,Y Co-ords   */
  2657.   y:=Div(Shl((wobj.y - stat.y),9),t)
  2658.   s:=Div(Shl(sz,9),t)                                 /* Calc size from C-Radius   */
  2659.   IF s>MAPWINSIZE THEN s:=MAPWINSIZE                  /* Limit s to MAPWINSIZE     */
  2660.   x2:=x+s                                             /* Calculate Box Dimensions  */
  2661.   y2:=y+s
  2662.   x1:=x-s
  2663.   y1:=y-s
  2664.   IF (x2>=0) AND (y2>=0) AND (x1<MAPWINSIZE) AND (y1<MAPWINSIZE) /* If in window draw it */
  2665.     Line(x1,y1,x2,y2,col)
  2666.     Line(x1,y2,x2,y1,col)
  2667.   ENDIF
  2668. ENDPROC
  2669.  
  2670. PROC coldraw(col:PTR TO colarea,colovr,pixdiv)
  2671.   DEF t,x1,y1,x2,y2,colr
  2672.  
  2673.   colr:=BLUE
  2674.   IF col=stat.actcol THEN colr:=RED                   /* If Active ColArea Draw Red */
  2675.   IF colovr>0 THEN colr:=colovr-1
  2676.  
  2677.   x1:=col.x
  2678.   y1:=col.y
  2679.   x2:=x1+col.width
  2680.   y2:=y1+col.depth
  2681.  
  2682.   IF pixdiv<>0
  2683.     t:=pixdiv                                         /* Use passed Pixel Divisor */
  2684.   ELSE
  2685.     t:=Div(Div(Shl(MAXCOORD,9),stat.zoom),MAPWINSIZE) /* Calculate Pixel Divisor  */
  2686.   ENDIF
  2687.  
  2688.   x1:=Div(Shl((x1 - stat.x),9),t)                     /* Calc Window X,Y Co-ords  */
  2689.   y1:=Div(Shl((y1 - stat.y),9),t)
  2690.   x2:=Div(Shl((x2 - stat.x),9),t)
  2691.   y2:=Div(Shl((y2 - stat.y),9),t)
  2692.  
  2693.   Line(x1,y1,x2,y1,colr)
  2694.   Line(x2,y1,x2,y2,colr)
  2695.   Line(x2,y2,x1,y2,colr)
  2696.   Line(x1,y2,x1,y1,colr)
  2697. ENDPROC
  2698.  
  2699. /**********************************/
  2700. /**** Select multiple wobjects ****/
  2701. /**********************************/
  2702.  
  2703. /* Sets selected flag on all wobjects within
  2704.    world co-ord rectangle specified
  2705.  
  2706.    Re-draws selected display to reflect selection status.
  2707.  
  2708.    To clear group select info call drawall()
  2709.  
  2710.    NOTE - Returns number of selected items
  2711. */
  2712.  
  2713. PROC groupselectwob(x1,y1,x2,y2)
  2714.   DEF wob:PTR TO wobitem,x,y,oldact,count
  2715.  
  2716.   IF x2<x1                                            /* Ensure coords ordered O.K.*/
  2717.     x:=x2
  2718.     x2:=x1
  2719.     x1:=x
  2720.   ENDIF
  2721.   IF y2<y1
  2722.     y:=y2
  2723.     y2:=y1
  2724.     y1:=y
  2725.   ENDIF
  2726.   oldact:=stat.actwobj                                /* Store current active obj  */
  2727.   stat.actwobj:=NIL                                   /* Clear current active obj  */
  2728.   count:=0                                            /* Initialise selected count */
  2729.   wob:=stat.woblist.head                              /* Get Start of wobitem List */
  2730.   WHILE wob.node.succ<>NIL                            /* If Valid wobitem          */
  2731.     x:=wob.wob.x
  2732.     y:=wob.wob.y
  2733.     IF (x>=x1) AND (x<=x2) AND (y>=y1) AND (y<=y2)    /* If in rectangle select    */
  2734.       wob.select:=1
  2735.       wobjdraw(wob.wob,RED+1,0)
  2736.       count:=count+1
  2737.     ELSE                                              /* Otherwise de-select       */
  2738.       wob.select:=0
  2739.       wobjdraw(wob.wob,0,0)
  2740.     ENDIF
  2741.     wob:=wob.node.succ                                /* Get Next wobitem          */
  2742.   ENDWHILE
  2743.   stat.actwobj:=oldact                                /* Restore current active obj*/
  2744. ENDPROC count
  2745.  
  2746. /*****************************************/
  2747. /**** Select Multiple Collision Boxes ****/
  2748. /*****************************************/
  2749.  
  2750. /* Returns number of selected collision boxes */
  2751.  
  2752. PROC groupselectclb(x1,y1,x2,y2)
  2753.   DEF col:PTR TO colitem,x3,y3,x4,y4,oldact,count
  2754.  
  2755.   IF x2<x1                                              /* Ensure coords ordered O.K.*/
  2756.     x3:=x2
  2757.     x2:=x1
  2758.     x1:=x3
  2759.   ENDIF
  2760.   IF y2<y1
  2761.     y3:=y2
  2762.     y2:=y1
  2763.     y1:=y3
  2764.   ENDIF
  2765.   oldact:=stat.actcol                                   /* Store current active colbox */
  2766.   stat.actcol:=NIL                                      /* Clear current active colbox */
  2767.   count:=0                                              /* Initialise selected count   */
  2768.   col:=stat.collist.head                                /* Get Start of colitem List   */
  2769.   WHILE col.node.succ<>NIL                              /* If Valid colitem            */
  2770.     x3:=col.col.x
  2771.     y3:=col.col.y
  2772.     x4:=x3+col.col.width
  2773.     y4:=y3+col.col.depth
  2774.     IF (x3>=x1) AND (x4<=x2) AND (y3>=y1) AND (y4<=y2)  /* If in rectangle select      */
  2775.       col.select:=1
  2776.       coldraw(col.col,RED+1,0)
  2777.       count:=count+1
  2778.     ELSE                                                /* Otherwise de-select         */
  2779.       col.select:=0
  2780.       coldraw(col.col,0,0)
  2781.     ENDIF
  2782.     col:=col.node.succ                                  /* Get Next colitem            */
  2783.   ENDWHILE
  2784.   stat.actcol:=oldact                                   /* Restore current active cbox */
  2785. ENDPROC count
  2786.  
  2787.  
  2788.